3
votes

I'm trying to convert a React based timer example to Typescript.

The class looks a little like this:

export class Container extends
    Component<IProps, IState> {

    private timerID: NodeJS.Timeout | undefined;  // stops a warning in DidMount

    constructor(props: IRevovlingContainerProps) {
        super(props);
        this.state = { date: new Date() } as any;
    }

    componentDidMount() {
        this.timerID = setInterval(
            () => this.tick(),
            1000
        );
    }

    componentWillUnmount() {
        clearInterval(this.timerID);  // error here on this.timerID
    }

    // ...

In componentWillUnmount() this.timerID has an error:

[ts] Argument of type 'Timeout | undefined' is not assignable to parameter of type 'number | undefined'. Type 'Timeout' is not assignable to type 'number'. [2345]

I've checked index.d.ts, which declares clearInterval():

declare function clearInterval(intervalId: NodeJS.Timeout): void;

So it looks like I am passing a correctly typed argument into clearInterval() and yet it expects a number. What should I be passing in please?

Edit: if I change my timerID declaration then an error appears in this.timerID in componentDidMount():

private timerID: number | undefined; 
Type 'Timeout' is not assignable to type 'number'.
3

3 Answers

5
votes

NodeJS.Timeout is meant to be used when you're running in the node environment. Since you want to use browser APIs, you'll have to use number as type for the timerID.

Also, the built-in functions should not resolve their types from node type definitions, in your case. If you have @types/node installed, please uninstall it if it's not required. That may be conflicting with the types that you need to be using.

2
votes

React uses JavaScript's vanilla setInterval, which returns a number. Check setInterval on MDN

The returned intervalID is a numeric, non-zero value

However, the return type you are referring to, NodeJS.Timeout, is the one returned by Node's setInterval. That is specific to Node.js.

Class: Timeout:

"This object is created internally and is returned from setTimeout() and setInterval()"

Timeout cannot be assigned to a number means that you are declaring the expected type as Node's Timeout, and what is actually received is a number.

-2
votes

If you defined it as any, it should work.

private timerID: any;