[我们看到像string|number
这样的简单推断类型被依赖项中的类型替换了在我们的输出声明文件中...因此string|number
在我们的import("csstype").AnimationIterationCountPropert
文件中变为d.ts
。
这会导致奇怪的上下文智能名称,如果符号链接的软件包无法访问TS编译器决定使用的依赖项,则可能在monorepos中引起问题。
这是一个可以返回字符串或数字的函数的示例:
const myFunc = (test: boolean) => {
let returnString = 'something';
let returnNumber = 1234;
// Returns either string or number
return test ? returnString : returnNumber;
};
TS推断类型:如果检查VSCode工具提示,则此函数的类型为:
(method) myFunc(test: boolean): string | number
[Compiled Declaration:到目前为止,一切看起来都不错。让我们使用tsc
进行编译。这是myFunc.d.ts
中的输出:
myFunc(test: boolean): import("csstype").AnimationIterationCountProperty
。
What?!我的源文件甚至都没有包含csstype
或对其进行任何提及。 AnimationIterationCountProperty
确实也共享类型string|number
,所以我猜想TS编译器正在尝试重用其类型,因为它共享相同的签名?
这会导致两个问题:
使用此库的代码不一定在其node_modules中具有csstype
,这会导致错误。
在使用代码中,当我将鼠标悬停在myFunc
上时,我的智能提示说返回类型为AnimationIterationCountProperty
,这在上下文中没有意义。此功能与CSS类型无关。
这是TS编译器的预期行为吗?还是这是某种错误?感谢您的帮助。
附加信息:
Typescript 3.6.3
如果我使用返回类型string|number
明确键入该函数,则不会发生。它输出期望的类型。
这是我们的tsconfig:
{
"compilerOptions": {
"module": "es6",
"moduleResolution": "node",
"noImplicitReturns": true,
"incremental": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"rootDir": "src",
"outDir": "lib",
"sourceMap": false,
"strict": true,
"importHelpers": true,
"target": "es2017",
"declaration": true,
"baseUrl": "src",
"jsx": "react"
},
"compileOnSave": true,
"include": ["src/**/*"],
"exclude": ["**/__tests__/**"]
}
对于联合类型,编译器将针对特定组合重新使用找到的名字(?!?)。
感谢@jcalz查找此GitHub问题:https://github.com/microsoft/TypeScript/issues/30759#issuecomment-480051225