- Created: 2024-07-28
Node.jsのTypeScriptサポートに関する議論を時系列でまとめたものです。
SWCを使ってTypeScriptの型を削除することで、Node.jsのTypeScriptサポートを実現するという提案からスタートした。
最初の懸念としては、Node.jsのLTSは3年保守する必要があるので、依存によってNode.jsのLTSサポートが難しくなるという話。 具体的には次のような懸念があった
- SWCがSemverではないこと
- TypeScriptがSemverではないこと
SWCについては、kdy1(SWC Author)からNode.jsが使うならそれ用のパイプラインを作るという話をした。
Node.js Loaders Team Meetingで、Node.jsにTypeScriptのサポートを入れたいという合意自体はある程度できた。 実際にtype stripでそれが実現できるかは実験する必要があり、undiciの例にならって外部のパッケージとして進めることでコアのリリースサイクルの外で進めることが提案された。
- module: add --experimental-strip-types by marco-ippolito · Pull Request #2 · marco-ippolito/node
- feat(binding): Create Wasm package for stripping only TypeScript by kdy1 · Pull Request #9124 · swc-project/swc
SWCにTypeScriptの型を削除するWasmパッケージが追加された。
この時点では次のような変換をしていた。
- const foo: string = "foo";
+ const foo = "foo";
TypeScriptの型を取り除いてJavaScriptへ変換するブルームバーグ社内での実験についての知見が共有された。
次のような空白の位置を維持しながら型を削除することで、Source Mapを不要にしつつ行番号を維持できるという話が共有された。 Source Mapの対応をしないことで、TypeScript to JavaScriptの変換が単純になりパフォーマンスを良くできるという話があった。
- const foo: string = "foo";
+ const foo = "foo";
これを受けて、 @swc/wasm-typescript
の strip-only
もこの対応をしている。
- feat(es/codegen): Implement
blank-space
codegen by kdy1 · Pull Request #9144 · swc-project/swc - feat(bindings/ts): Add transform/strip-only mode by kdy1 · Pull Request #9138 · swc-project/swc
SWCのPlaygroundにも strip-only
が追加された。
問題として"TypeScriptのサポート"といったときに、型を取り除くだけで実現できない機能があるため、TypeScriptのサポートとは言えないという話がある。
具体的には、enum
、namespace
、decoratorなど、TypeScriptが型だけではなくコードとして出力する例外的な機能もすでに存在している。
これらのコードを出力する機能が今後増えると、Node.jsのLTSは守れなくなる問題が存在している。
またTypeScriptチームからも"TypeScriptサポート"といった場合のユーザーがどう思うかについての懸念があった。
これについてNode.jsのLoaders TeamとTypeScript Teamの間で議論が行われた。
議論結果は次のコメントにまとめられている。
TypeScriptチームとしては、"TypeScriptサポート"といった場合には、enum
やnamespace
も含めたものを想定している。
一方で、このようなJavaScriptのコードを出力する機能(型を取り除くだけで実現できない機能)を増やす可能性はかなり低いという話もされた。
また、Node.jsがTypeSriptサポートをした場合に、.ts
をnpmのregistryにpublishすることについての懸念と議論も行われた。
課題は色々あるが、ひとまずはNode.jsがTypeScriptサポートについてのIterationを進めること自体のブロッカーはないという結論になった。
そのあともNode TSCで議論が行われて、Node.jsのユーザー体験に関わる部分なのでNode.js Loaders Teamだけではなくもっと広い範囲で話したほうが良いかもしれないという話がされた。
また、node_modules/
に対して現状の実装では適応するべきじゃないことやNode.jsとTypeScript Teamのコラボレーションをどうやってやるかなどについても議論された。
- 2024-07-24-Node.js Technical Steering Committee meeting - YouTube
- doc: add minutes for meeting 24 July 2024 by mhdawson · Pull Request #1601 · nodejs/TSC
@swc/wasm-typescript
をラップしたAmaroというモジュールをNode.jsに追加するPRがマージされた。
次のような実験的なフラグを使って、TypeScriptのコードから型を取り除いたJavaScriptとして実行できるようになった。
node --experimental-strip-types main.ts
Node.jsのTypeScriptサポートについてのロードマップは次のIssueで議論されている。
まだenum
やnamespace
などをどうするか、拡張子がないファイルのimportの対応、node_modules/
以下のファイルの.tsは扱うべきなのか(npmにpublishされたものをどうするかという話)、@swc/wasm-typescript
を使って実現しているがパフォーマンスを考えるとネイティブに実装するかなどの論点が残っている。
Node.js CoreでのTypeScriptサポートについて議論するリポジトリが作られた
module: add --experimental-transform-types flag by marco-ippolito · Pull Request #54283 · nodejs/node
--experimental-transform-types
フラグを元にenum
とnamespace
の変換をサポートした。
Tsconfig option to disallow features requiring transformations which are not supported by Node.js' --strip-types · Issue #59601 · microsoft/TypeScript
Node.jsのTypeScriptサポートは限定的で、tsconfig.jsonでそのNoe.jsのTypeScriptサポートに対応するオプションをまとめて有効化したいというIssue
2022年頃からtc39側でも Type Annotationsという名前で、
「Typescriptをフルサポートするのはしんどいけど、型部分を無視する機能だけ先にどう?」って提案されている事を思い出した。
https://github.com/tc39/proposal-type-annotations
typescript側がenumやnamespaceなどJavascirptコードを出力する機能と、エディタ上で型ヒント・エラーを出すだけの機能を分離してくれるのが一番手っ取り早そうだが・・・