"TS2322: Type 'Timeout' is not assignable to type 'number'" when running unit tests
Solution 1
You could try with using window.setTimeout
instead of just setTimeout, this way the typescript one will be explicitly used
Solution 2
You can use:
let timeoutId: null | ReturnType<typeof setTimeout> = null
...
timeoutId = setTimeout(...)
It'll pick correct declaration depending on your context.
I'm seeing this discrepency when using vscode/tsc (NodeJS.Timeout) and running ts-jest (number). This is the only way the whole thing typechecks on both sides.
Solution 3
By default, typescript includes all ./node_modules/@types/*
. If you have ./node_modules/@types/node
there, its timeout typings will override the web typing (that returns a number, and not a NodeJS.Timeout
).
You can remedy to that by explicitly emptying your types in your tsconfig.json
:
{
"compilerOptions": {
"types": []
}
}
Realistically you're probably in a project where you need other types and libs so you might wanna bring back ES and DOM libs:
{
"compilerOptions": {
"types": [],
"lib": ["ESNext", "DOM"]
}
}
dawsonc623
Updated on July 20, 2022Comments
-
dawsonc623 almost 2 years
I have two TypeScript packages, and one package (Package A) depends on the other (Package B). Each package has a unit test set up using Karma. When I run unit tests for each individually after installing all dependencies from NPM, the unit tests run fine. However, if I use
npm link package-b
in Package A and run Package A's unit tests then, I get the error stated in the title: "TS2322: Type 'Timeout' is not assignable to type 'number'."The line in question is a call to
setTimeout
. After digging, I found that while running the tests separately withoutnpm link
, TypeScript correctly identifies thesetTimeout
signature intypescript/lib/lib.dom
as the desired type, but in the failing case after usingnpm link
it is using using Node'ssetTimeout
signature in@types/node/index
. I confirmed this by changing the return type onsetTimeout
tostring
and observing the same error withstring
in the place ofTimeout
.What I am not certain of is why the TypeScript compiler has decided to use the alternative definition in this specific case, nor how I can convince it to use the desired definition. I am happy to post some code, but I am not sure what would be useful in this case given all that is on the failing line is the
setTimeout
call.