我设法发布了一个模块,其中使用了错误的三斜杠指令,导致无法使用的类型定义。我认为Typescript在编译过程中生成声明时本应该捕获此错误。
TypeScript版本:3.8.0-dev.20200131
搜索词:
三斜杠指令相对路径
代码
让我们构建一个最小的应用,它消耗自定义类型定义。为了方便起见,我会将其放在types
中,并指定typeRoots
,但这也适用于可能出现在node-modules/@types/some_module
中的已发布的模块。
├── package.json
├── tsconfig.json
├── src
| └── main.ts
└── types
└── package
├── index.d.ts
└── type.d.ts
- package.json*
{
"name": "reference-type-paths",
"version": "1.0.0",
"private": true,
"scripts": {
"build": "rm -rf dist/*; tsc"
},
"devDependencies": {
"typescript": "^3.8.0-dev.20200131"
}
}
- tsconfig.json*
{
"compilerOptions": {
"target": "ES2019",
"module": "commonjs",
"declaration": true,
"outDir": "./dist",
"strict": true,
"typeRoots": ["./types"]
}
}
我们设置了一些TS文件,以使用模块中定义的自定义类型。
- src/main.ts*
export class Container {
readonly data: Optional<string>;
}
不幸的是,我们的模块错误地使用了带有路径的types
三斜杠指令。
- types/package/index.d.ts*
/// <reference types="./type" />
- types/package/type.d.ts*
declare type Optional<T> = T | null | undefined;
最后,我们运行tsc
。
预期行为:
Typescript不应该发出包含无效“类型”路径的声明文件。在使用路径(或相对于typeRoots的路径)时,应将/// <reference types=
作为错误在编译过程中捕获,以防止生成无法使用的声明文件。
我们有/// <reference path=
,这里应该使用它。如果types/package/index.d.ts
包含/// <reference path="./type.d.ts" />
,Typescript会产生:
- dist/main.d.ts*
/// <reference types="package" />
export declare class Container {
readonly data: Optional<string>;
}
然后正确解析。
或者,可能会生成相对于typeRoots
目录的路径:
- dist/main.d.ts*
/// <reference types="package/type" />
export declare class Container {
readonly data: Optional<string>;
}
https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html#-reference-types- states:
解析这些包名的过程与解析导入语句中的模块名的过程相似。很容易想到,三斜杠引用类型指令就像是对声明包的导入。
这并不意味着在三斜杠类型引用中使用相对路径是不合适或危险的。
实际行为:
不幸的是,实际上得到的是模块的三斜杠指令保留的相对路径。
- dist/main.d.ts*
/// <reference types="./type" />
export declare class Container {
readonly data: Optional<string>;
}
这个定义是无法使用的。如果我们发布它,我们模块的消费者将看到错误,因为type
相对于他们的typeRoots
不存在。
这特别令人沮丧,因为只有在模块具有错误指令的二级依赖项中才会被注意到。在这个例子中,我可以依赖于package
,显然可以成功编译并生成自己的声明,发布它们,然后有人依赖于我的包并尝试消费我的声明时遇到编译错误。
Playground链接:
不可能,取决于生成d.ts声明文件。
2条答案
按热度按时间sdnqo3pr1#
解决方法
TS
3.8.x
如果我添加一个类型导入:
那么我就可以得到一个可用的定义文件:
TS
3.7.5
,3.7.3
我没有阻止发布包含不可达路径的定义的方法,但是依赖项可以使用自己的三斜杠声明来解决这个问题,例如,如果有人从这个例子中安装了
main.d.ts
作为依赖项,将/// <reference types="package/type"/>
添加到他们的.ts
文件中可以让他们编译通过。7vhp5slm2#
关于这个的更新情况?
编辑:我不想显得粗鲁,但我们也遇到了同样的问题。我们希望这个问题能得到解决,如果有办法帮助解决的话,我们会很乐意知道。