Using tsc v1.1.0-1 we get an error when compiling :
error TS2323: Type 'Timer' is not assignable to type 'number'.
the following code throws the compile error:
this.sTimeout = setTimeout( () => this.showDelay() , 250 );
sTimeout is defined as a number ( private var ) .
Please post a complete example. The information given so far is not enough to reproduce the issue:
class Foo {
private sTimeout: number;
showDelay() { }
bar() {
setTimeout(() => this.showDelay(), 250);
}
}
There is no built-in type called Timer
so it's likely that the setTimeout
you're calling is not window.setTimeout
.
Should have made an example - was a little rushed earlier. Here you go:
class Foo {
private sTimeout: number; // Storing Timeout ID - to clear it - if needed
private showDelay() { }
constructor() {
this.sTimeout = setTimeout(() => this.showDelay(), 250);
}
}
Throws the following error:
Using tsc v1.1.0-1
/tests/Foo.ts(5,3): error TS2323: Type 'Timer' is not assignable to type 'number'.
For now I have fixed it using by typing sTimeout to any .
This does not repro for me. What happens when you F12 setTimeout
?
Not sure what you mean by F12 ? .
"Go to definition"
Again, there is no built-in type called Timer
, so your code must be referring to some other type. Please try out your example in a file by itself, or figure out where in your project this Timer
is coming from. I'm guessing that setTimeout
isn't referring to the built-in function, but rather some other user-defined function that has a different return value.
Tried the example by itself: looks like it is caused by a component in my toolchain or other code - sorry for taking your time. Thank you ... Closed...
For future readers, I came across this error because of the node.js definitely-typed definitions. The solution is to use the full name of the type, which is NodeJS.Timer
not Timer
(which sadly is what the Typescript transpiler suggests, and doesn't work).
@jdfreder time flies - the future is here
anyway I had the same issue: error TS2352: Neither type 'Timer' nor type 'number' is assignable to the other.
even though I have the implicit reference defined at the top of the file /// <reference path="node_modules/typescript/lib/lib.d.ts" />
still doesn't work.
The main problem is that one of our 3rd party npm package (angular2) have TS + typings (node, and others) included in the package.
@rixrix (and for anyone else who finds this) I had a similar problem until I realized I wasn't passing in the correct parameters.
Compare this, which requires the second parameter ms
and returns a NodeJS.Timer
:
function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;
...and this, which does makes the second parameter timeout
optional and returns a number
:
function setTimeout(handler: any, timeout?: any, ...args: any[]): number;
Based on these two functions TS correctly selects an appropriate overload, so if you get error TS2352: Neither type 'Timer' nor type 'number' is assignable to the other
make sure you specify a timeout!
Hi @Penryn thanks for the heads up!
I think my previous comment is a testament of not giving enough details as I can't remember anymore the exact details about the said error message. sorry.
On top of my head, the issue that we had before was when we do incremental upgrades of our spin off web app written in Angular2(alpha releases). Our main code base (ng1 and ng2) is written in TypeScript (with bower components, bunch of other typings, and few custom typings), and Angular2 at that time were shipping typings as well, node typings etc. With our node typings (outdated version) and ng2 node typings (and possibly other typings), effectively the TS compiler gets confused about dups typings. In our case, we could have manually modify the offending typings but it's just too much work knowing that some point we'll have to pull out the latest version(s)
I think this has been resolved in recent Angular2 releases as we'll have to manually install the required typings.
cheers
@RyanCavanaugh have same issue. I look, that I have two deffinitions for setTimeout. One returns number
and the other returns NodeJS.Timer
.
Just use window.setTimeout
instead.
Why does the NodeJS.Timer
require a special type? It's still just going to return a number
right? Am I missing something?
@cchamberlain Node actually returns an entire Timer class: https://nodejs.org/api/timers.html
So not just a number
in this case.
@Penryn - TIL 👍
For those curious, the reason this is happening is that setTimeout
in node.js returns a different thing than setTimeout
inside the browser. The browser's setTimeout just returns a number; in node.js setTimeout returns a big Timer object.
So the reason you're seeing this problem is almost certainly because you've intended to target the web, but you've pulled in node definitions.
@johnfn could also be isomorphic code intended to target browser and node.
For others coming in here using the setTimeout
or setInterval
, use window.setTimeout
or interval
so tsc knows you're using the web browser's function (which returns number) and not NodeJS's function (which returns something else).
To add on to @AskYous , if you have @types/node
in the packages, use window.setInterval
to avoid the type failure.
For who is using @angular
with @angular-cli
make sure you have the type node on your tsconfig.app.json
as well.
Eq:
tsconfig.app.json
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"module": "es6",
"baseUrl": "",
"types": ["node"] --> ADD THIS
},
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}
I found it here: https://stackoverflow.com/a/43952363/3415716
Maybe you have import a package that has a function with name setTimeout()
.
Just use window.setTimeout
instead of setTimeout
to solve the problem :)
in node environment type is NodeJS.Timer
use global.setTimeout
and in browser environment type is number
use window.setTimeout
today after installing npm i @types/react @types/react-dom --save-dev
the @types\node
leaked into node_modules
and thus it was causing the Timer
error
Like @nippur72 , I ran into this today with react-dom
. I think the simplest solution is to update the @types
package to not depend on Node when a browser environment is expected, hence: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/21310#issuecomment-367919251
Most helpful comment
Just use
window.setTimeout
instead.