1. ホーム
  2. タイプスクリプト

[解決済み】TypeScript - 正しいバージョンのsetTimeoutを使用する(ノードとウィンドウの比較)

2022-04-21 05:57:14

質問

古いTypeScriptのコードを最新のコンパイラバージョンにアップグレードしているのですが、その際に setTimeout . このコードでは、ブラウザの setTimeout という関数があり、これは数値を返します。

setTimeout(handler: (...args: any[]) => void, timeout: number): number;

しかし、コンパイラはこれをノード実装に解決し、NodeJS.Timerを返します。

setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer;

このコードはnodeで実行されませんが、nodeの型付けは何か他のもの(何かは不明)への依存として引き込まれています。

のバージョンを選択するようにコンパイラに指示するにはどうすればよいでしょうか? setTimeout を使用したいのですが?

以下は問題のコードです。

let n: number;
n = setTimeout(function () { /* snip */  }, 500);

これは、コンパイラーエラーを発生させます。

TS2322: タイプ 'Timer' はタイプ 'number' に割り当てられません。

解決方法は?

2021年版アップデート

Akxeの回答 提案する ReturnType<Type> のテクニックは、Typescript 2.3 で導入されました。

let n: ReturnType<typeof setTimeout>;
n = setTimeout(cb, 500);

これは素晴らしいことで、明示的なキャストよりも好まれるようです。しかし、この場合の "n" の結果型は "NodeJS.Timeout" であり、以下のように使用することが可能です。

let n: NodeJS.Timeout;
n = setTimeout(cb, 500);

ReturnType/NodeJS.Timeoutアプローチの唯一の問題は、ブラウザ固有の環境での数値演算はまだキャストを必要とすることです。

if ((n as unknown as number) % 2 === 0) {
  clearTimeout(n);
}

オリジナルの回答

変数宣言に影響を与えない回避策です。

let n: number;
n = setTimeout(function () { /* snip */  }, 500) as unknown as number;

また、ブラウザ固有の環境下では window オブジェクトをキャストせずに使用することができます。

let n: number;
n = window.setTimeout(function () { /* snip */  }, 500);