"TS2322: Type 'Timeout' is not assignable to type 'number'" 当 运行 单元测试时
"TS2322: Type 'Timeout' is not assignable to type 'number'" when running unit tests
我有两个 TypeScript 包,一个包(包 A)依赖于另一个包(包 B)。每个包都有一个使用 Karma 设置的单元测试。在从 NPM 安装所有依赖项后,当我 运行 对每个单独进行单元测试时,单元测试 运行 正常。但是,如果我在包 A 中使用 npm link package-b
并在包 A 的单元测试中使用 运行,则会出现标题中所述的错误:"TS2322: Type 'Timeout' is not assignable to type 'number'."
有问题的行是对 setTimeout
的调用。挖掘之后,我发现虽然 运行 在没有 npm link
的情况下单独测试,TypeScript 正确地将 typescript/lib/lib.dom
中的 setTimeout
签名识别为所需的类型,但在失败的情况下使用 npm link
它在 @types/node/index
中使用 Node 的 setTimeout
签名。我通过将 setTimeout
上的 return 类型更改为 string
并用 string
代替 Timeout
观察到相同的错误来确认这一点。
我不确定的是 为什么 TypeScript 编译器决定在这种特定情况下使用替代定义,也不确定我如何说服它使用所需的定义。我很高兴 post 一些代码,但我不确定在这种情况下什么会有用,因为失败行上的所有内容都是 setTimeout
调用。
您可以尝试使用 window.setTimeout
而不是 setTimeout,这样 typescript 就会被明确使用
您可以使用:
let timeoutId: null | ReturnType<typeof setTimeout> = null
...
timeoutId = setTimeout(...)
它会根据您的上下文选择正确的声明。
我在使用 vscode/tsc (NodeJS.Timeout) 和 运行 ts-jest(数字)时看到了这种差异。这是整个事情在双方都进行类型检查的唯一方法。
您可以使用类似的东西:
let myTimeOut: NodeJS.Timeout | null = null;
myTimeOut = setTimeout(...);
然后当您将变量重置为初始状态时,您可以简单地:
myTimeOut = null;
默认情况下,打字稿includes all ./node_modules/@types/*
。如果那里有 ./node_modules/@types/node
,它的超时输入将覆盖网络输入(returns 一个数字,而不是 NodeJS.Timeout
)。
您可以通过显式清空 tsconfig.json
:
中的类型来补救
{
"compilerOptions": {
"types": []
}
}
实际上,您可能在一个需要其他类型和库的项目中,因此您可能想带回 ES 和 DOM 库:
{
"compilerOptions": {
"types": [],
"lib": ["ESNext", "DOM"]
}
}
我有两个 TypeScript 包,一个包(包 A)依赖于另一个包(包 B)。每个包都有一个使用 Karma 设置的单元测试。在从 NPM 安装所有依赖项后,当我 运行 对每个单独进行单元测试时,单元测试 运行 正常。但是,如果我在包 A 中使用 npm link package-b
并在包 A 的单元测试中使用 运行,则会出现标题中所述的错误:"TS2322: Type 'Timeout' is not assignable to type 'number'."
有问题的行是对 setTimeout
的调用。挖掘之后,我发现虽然 运行 在没有 npm link
的情况下单独测试,TypeScript 正确地将 typescript/lib/lib.dom
中的 setTimeout
签名识别为所需的类型,但在失败的情况下使用 npm link
它在 @types/node/index
中使用 Node 的 setTimeout
签名。我通过将 setTimeout
上的 return 类型更改为 string
并用 string
代替 Timeout
观察到相同的错误来确认这一点。
我不确定的是 为什么 TypeScript 编译器决定在这种特定情况下使用替代定义,也不确定我如何说服它使用所需的定义。我很高兴 post 一些代码,但我不确定在这种情况下什么会有用,因为失败行上的所有内容都是 setTimeout
调用。
您可以尝试使用 window.setTimeout
而不是 setTimeout,这样 typescript 就会被明确使用
您可以使用:
let timeoutId: null | ReturnType<typeof setTimeout> = null
...
timeoutId = setTimeout(...)
它会根据您的上下文选择正确的声明。
我在使用 vscode/tsc (NodeJS.Timeout) 和 运行 ts-jest(数字)时看到了这种差异。这是整个事情在双方都进行类型检查的唯一方法。
您可以使用类似的东西:
let myTimeOut: NodeJS.Timeout | null = null;
myTimeOut = setTimeout(...);
然后当您将变量重置为初始状态时,您可以简单地:
myTimeOut = null;
默认情况下,打字稿includes all ./node_modules/@types/*
。如果那里有 ./node_modules/@types/node
,它的超时输入将覆盖网络输入(returns 一个数字,而不是 NodeJS.Timeout
)。
您可以通过显式清空 tsconfig.json
:
{
"compilerOptions": {
"types": []
}
}
实际上,您可能在一个需要其他类型和库的项目中,因此您可能想带回 ES 和 DOM 库:
{
"compilerOptions": {
"types": [],
"lib": ["ESNext", "DOM"]
}
}