← ./articles-ja

tscは通るのにVS CodeだけsetTimeoutが見つからない時はtypes nodeを見る

TypeScriptで、CLIとVS Codeの結果がズレることがあります。

CLIでは通ります。

npx tsc --noEmit

でもVS Codeでは次のようなエラーが出ます。

Cannot find name 'setTimeout'
Cannot find name 'process'
Cannot find name 'Buffer'

@types/node は入っているのにVS Codeだけ怒る場合、tsconfig.json にNode型を明示すると直ることがあります。

原因

TypeScript CLIとVS CodeのTypeScript Language Serverは、同じように見えて初期化のタイミングや型解決が完全には一致しません。

module: "Node16" のような設定では、CLI側は @types/node を解決できても、VS Code側がNodeのglobal型を拾えないことがあります。

その結果、次の状態になります。

tsc: 通る
VS Code: 赤線が出る

修正

types: ["node"] を明示します。

{
  "compilerOptions": {
    "module": "Node16",
    "target": "ES2022",
    "lib": ["ES2022"],
    "types": ["node"]
  }
}

その後、VS CodeでTypeScript projectをreloadします。

Ctrl+Shift+P -> TypeScript: Reload Projects

DOMを足してごまかさない

Node.jsで動くコードに、安易にDOM libを足すのは避けます。

{
  "lib": ["ES2022", "DOM"]
}

これで一部のエラーは消えるかもしれませんが、実行時に存在しないbrowser globalまで型上は存在することになります。

Node.js専用なら、次のほうが明確です。

{
  "lib": ["ES2022"],
  "types": ["node"]
}

チェックリスト

VS Codeと tsc がズレる時は、次を確認します。

  • @types/node が入っているか
  • "types": ["node"] を明示しているか
  • lib が実行環境と合っているか
  • VS CodeのTypeScript projectをreloadしたか
  • 最後に npx tsc --noEmit も通るか

まとめ

tsc は通るのにVS CodeだけNode.js globalを見失うなら、Node型を明示してください。

CLIだけでなく、エディタのLanguage Serverにも同じ前提を読ませるのがポイントです。

参考