TechFeed Experts Night#11 「ついに来る!TypeScript5.0の新機能」
ついに来る!TypeScript 5.0の新機能TechFeed Experts Night#11uhyo (株式会社バベル プリンシパルエンジニア)
View Slide
おさらい: TypeScriptのリリースサイクル3ヶ月に1回のリリースサイクル(4.9と5.0が4ヶ月空いているのは年末休みのため?)TypeScript 4.8 TypeScript 4.9 TypeScript 5.02022年8月公開 2022年11月公開 2023年3月公開(予定)
おさらい: TypeScriptのリリースサイクルTypeScriptはsemantics versioningを採用していないので、5.0は他に比べて特別なリリースというわけではない。TypeScript 4.8 TypeScript 4.9 TypeScript 5.02022年8月公開 2022年11月公開 2023年3月公開(予定)
TypeScript 5.0概観• デコレータが実装!• あとはオプションの追加・変更が多く、バンドラ関連のサポートが充実
①Stage 3 デコレータ実装デコレータのプロポーザルがStage 3になり安定したため、TypeScriptに実装される。これまでの古い仕様に基づいた実装はLegacy Decoratorsとしてサポート継続https://github.com/microsoft/TypeScript/pull/50820experimentalDecorators: false experimentalDecorators: true~TS 4.9 無 Legacy DecoratorsTS 5.0~ Stage3 Decorators Legacy Decorators※発表時点でまだPRがマージされていないため、TS 5.1以降にずれる可能性もあります。
② 古いオプションの非推奨化が始まるTypeScriptには多くのコンパイラオプションがあるが、エコシステムの変化や型システムの進化によりユースケースが消滅したオプションもあるので廃止が始まる。TypeScript 5.0: 廃止対象のオプションに対するwarningの表示TypeScript 5.5: オプションのnoop化TypeScript 6.0: 廃止(指定するとエラーが発生)https://github.com/microsoft/TypeScript/issues/51000
廃止対象オプション使われないオプションの中でもかなり古いものが選ばれた印象。もう需要が無い系• charset• noImplicitStrict• out型システムの進化で必要が無くなった系• keyofStringsOnly• noStrictGenericChecks移行期間さすがに終わりだよ系• suppressExcessPropertyErrors• suppressImplicitAnyIndexErrorsTypeScriptの型チェックが厳しくなる際に後方互換性のために追加されたが、さすがにもう移行終わってそうなやつ
③ .tsによるimportが解禁新オプションallowImportingTsExtensions: true を設定することで、import { … } from “./foo.ts” が可能になる。制約: noEmit: true または emitDeclarationOnly: true と併用が必要。(JavaScriptにトランスパイルしない設定の場合のみ許可される)
.tsによるimport解禁の背景これまでTypeScriptは import “./foo.ts” の実装を拒んでいた。理由: トランスパイル後は “foo.js” に直す必要があるが、ランタイムの挙動を変えることになるのでTypeScriptとしてはやりたくない。バンドラなら.jsに直さなくてもバンドルができるので解禁された。(モジュール解決のホストであるバンドラが.tsの解決をサポートしているので、.tsでimportするコードを妥当なTypeScriptコードとして扱うことが正当化される)
④ モジュール解決に関する設定の追加TypeScriptは独自にモジュール解決(import先の決定・読み込み)を行っているが、その挙動を調整するオプションが新たに追加される。TypeScript 5.0で追加される見込みのオプション:• moduleResolution: “bundler” ― バンドラと相性がいい設定• 付随する新オプションたち: resolvePackageJsonExports,resolvePackageJsonImports, customConditionshttps://github.com/microsoft/TypeScript/pull/51669
バンドラ向けモジュール解決の概要バンドラの特徴:• TypeScriptファイル間で直接import/exportできる。(中間表現としてのJavaScriptを出力する必要がない)• package.jsonの imports/exportsを解釈できる。(もともとnode.jsの機能だが、バンドラにもサポートされている)moduleResolution: “bundler” の機能:• .tsでのimportや拡張子なしのimportも可能。• package.jsonのimports/exportsを解釈する。
変更の背景package.jsonのimports/exportsフィールドのサポート:特にexportsフィールドは “my-package/foo”のようなサブパスのimportの挙動が制御できるのでとても便利だが、従来はmoduleResolution: “node16” 下でのみのサポートだった。理由: そもそもpackage.jsonがNode.jsの機能なので、デフォルトでサポートするのは妥当ではない。
変更の背景②最近のバンドラはpackage.json関連の機能をサポートしているので、それに合わせてmoduleResolution: “bundler” でもpackage.json関連の機能が有効化される。嬉しい点: moduleResolution: “node16”はimportに拡張子が必須になるためバンドラ環境で使うのが難しかったが、今回の機能追加によりバンドラでもpackage.jsonの機能が使えるようになった。また、バンドラの多様性が反映され、細かい挙動が調整可能になった。(オプション4つ新設)
⑤ 任意の拡張子をimportするオプションTypeScript 5.0で追加されるallowArbitraryExtensions: trueを使用すると、 import “./foo.css” など任意の拡張子をimportできるようになる。https://github.com/microsoft/TypeScript/pull/51435
⑤ 任意の拡張子をimportするオプションTypeScript 5.0で追加されるallowArbitraryExtensions: trueを使用すると、 import “./foo.css” など任意の拡張子をimportできるようになる。Q. 前からできたのでは?https://github.com/microsoft/TypeScript/pull/51435
⑤ 任意の拡張子をimportするオプションTypeScript 5.0で追加されるallowArbitraryExtensions: trueを使用すると、 import “./foo.css” など任意の拡張子をimportできるようになる。Q. 前からできたのでは?A. moduleResolution: “node16” だとできなかった。Node.jsではimport時に .js という拡張子が必要なので、それ以外の拡張子は許可されていなかった。https://github.com/microsoft/TypeScript/pull/51435
CommonJS時代の型定義ファイル解決従来、require(“./foo.css”) に対する型定義ファイルはfoo.css.d.ts として用意できた。ただし、実はfoo.css.d.tsはfoo.css.js に対する定義ファイル。require(“./foo.css”)↓CommonJS的解釈foo.css.js ←型定義foo.css.d.ts
Node.jsのES Modulesだと……Node.jsのESMだと拡張子を省略できない。import “./foo.css” ←型定義???↓別物↑import “./foo.css.js” ←型定義foo.css.d.ts
Node.jsのES Modulesだと……Node.jsのESMだと拡張子を省略できない。import “./foo.css” ←型定義foo.d.css.ts↓別物import “./foo.css.js” ←型定義foo.css.d.tsTypeScript 5.0で .d.ext.ts が導入される。CommonJS時代には真剣に考慮する必要がなかった拡張子に関するサポートを拡張した結果生まれた。
総評TypeScriptはこれまでモジュール解決をむやみに拡張可能にするのではなく、現実のユースケースに合致することを重視してきた。今回もその流れは変わらず、Node.jsでの非JSファイル読み込みやバンドラという具体的なユースケースを念頭においた機能追加だった。昔の独自路線(enumとか)を反省してか、TypeScriptは独自の仕様を作ったり普及させたりしないようにかなり気を付けているように見える。
所感フロントエンド開発でpackage.jsonのexportsを使いたい際にネックになるのがTypeScriptだったので、5.0でそこが解消されるのはとても嬉しい。デコレータも正式版が実装されたら設計に取り入れたい。おわり