$30 off During Our Annual Pro Sale. View Details »

ついに来る!TypeScript5.0の新機能

uhyo
January 18, 2023

 ついに来る!TypeScript5.0の新機能

TechFeed Experts Night#11 「ついに来る!TypeScript5.0の新機能」

uhyo

January 18, 2023
Tweet

More Decks by uhyo

Other Decks in Technology

Transcript

  1. ついに来る!
    TypeScript 5.0の新機能
    TechFeed Experts Night#11
    uhyo (株式会社バベル プリンシパルエンジニア)

    View Slide

  2. おさらい: TypeScriptのリリースサイクル
    3ヶ月に1回のリリースサイクル
    (4.9と5.0が4ヶ月空いているのは年末休みのため?)
    TypeScript 4.8 TypeScript 4.9 TypeScript 5.0
    2022年8月公開 2022年11月公開 2023年3月公開(予定)

    View Slide

  3. おさらい: TypeScriptのリリースサイクル
    TypeScriptはsemantics versioningを採用していないので、
    5.0は他に比べて特別なリリースというわけではない。
    TypeScript 4.8 TypeScript 4.9 TypeScript 5.0
    2022年8月公開 2022年11月公開 2023年3月公開(予定)

    View Slide

  4. TypeScript 5.0概観
    • デコレータが実装!
    • あとはオプションの追加・変更が多く、バンドラ関連のサポー
    トが充実

    View Slide

  5. ①Stage 3 デコレータ実装
    デコレータのプロポーザルがStage 3になり安定したため、
    TypeScriptに実装される。
    これまでの古い仕様に基づいた実装はLegacy Decoratorsとし
    てサポート継続
    https://github.com/microsoft/TypeScript/pull/50820
    experimentalDecorators: false experimentalDecorators: true
    ~TS 4.9 無 Legacy Decorators
    TS 5.0~ Stage3 Decorators Legacy Decorators
    ※発表時点でまだPRがマージされていないため、TS 5.1以降にずれる可能性もあります。

    View Slide

  6. ② 古いオプションの非推奨化が始まる
    TypeScriptには多くのコンパイラオプションがあるが、
    エコシステムの変化や型システムの進化によりユースケースが
    消滅したオプションもあるので廃止が始まる。
    TypeScript 5.0: 廃止対象のオプションに対するwarningの表示
    TypeScript 5.5: オプションのnoop化
    TypeScript 6.0: 廃止(指定するとエラーが発生)
    https://github.com/microsoft/TypeScript/issues/51000

    View Slide

  7. 廃止対象オプション
    使われないオプションの中でもかなり古いものが選ばれた印象。
    もう需要が無い系
    • charset
    • noImplicitStrict
    • out
    型システムの進化で必要が無くなった系
    • keyofStringsOnly
    • noStrictGenericChecks
    移行期間さすがに終わりだよ系
    • suppressExcessPropertyErrors
    • suppressImplicitAnyIndexErrors
    TypeScriptの型チェックが厳しく
    なる際に後方互換性のために追加
    されたが、
    さすがにもう移行終わってそうな
    やつ

    View Slide

  8. ③ .tsによるimportが解禁
    新オプションallowImportingTsExtensions: true を設定するこ
    とで、import { … } from “./foo.ts” が可能になる。
    制約: noEmit: true または emitDeclarationOnly: true と併用が必要。
    (JavaScriptにトランスパイルしない設定の場合のみ許可される)

    View Slide

  9. .tsによるimport解禁の背景
    これまでTypeScriptは import “./foo.ts” の実装を拒んでいた。
    理由: トランスパイル後は “foo.js” に直す必要があるが、ランタイムの
    挙動を変えることになるのでTypeScriptとしてはやりたくない。
    バンドラなら.jsに直さなくてもバンドルができるので解禁された。
    (モジュール解決のホストであるバンドラが.tsの解決をサポートしている
    ので、.tsでimportするコードを妥当なTypeScriptコードとして扱うこと
    が正当化される)

    View Slide

  10. ④ モジュール解決に関する設定の追加
    TypeScriptは独自にモジュール解決(import先の決定・読み込み)
    を行っているが、その挙動を調整するオプションが新たに追加され
    る。
    TypeScript 5.0で追加される見込みのオプション:
    • moduleResolution: “bundler” ― バンドラと相性がいい設定
    • 付随する新オプションたち: resolvePackageJsonExports,
    resolvePackageJsonImports, customConditions
    https://github.com/microsoft/TypeScript/pull/51669

    View Slide

  11. バンドラ向けモジュール解決の概要
    バンドラの特徴:
    • TypeScriptファイル間で直接import/exportできる。
    (中間表現としてのJavaScriptを出力する必要がない)
    • package.jsonの imports/exportsを解釈できる。
    (もともとnode.jsの機能だが、バンドラにもサポートされている)
    moduleResolution: “bundler” の機能:
    • .tsでのimportや拡張子なしのimportも可能。
    • package.jsonのimports/exportsを解釈する。

    View Slide

  12. 変更の背景
    package.jsonのimports/exportsフィールドのサポート:
    特にexportsフィールドは “my-package/foo”のようなサブパス
    のimportの挙動が制御できるのでとても便利だが、
    従来はmoduleResolution: “node16” 下でのみのサポートだっ
    た。
    理由: そもそもpackage.jsonがNode.jsの機能なので、デフォルトでサポー
    トするのは妥当ではない。

    View Slide

  13. 変更の背景②
    最近のバンドラはpackage.json関連の機能をサポートしている
    ので、それに合わせてmoduleResolution: “bundler” でも
    package.json関連の機能が有効化される。
    嬉しい点: moduleResolution: “node16”はimportに拡張子が必須になるため
    バンドラ環境で使うのが難しかったが、今回の機能追加によりバンドラでも
    package.jsonの機能が使えるようになった。
    また、バンドラの多様性が反映され、細かい挙動が調整可能になった。
    (オプション4つ新設)

    View Slide

  14. ⑤ 任意の拡張子をimportするオプション
    TypeScript 5.0で追加される
    allowArbitraryExtensions: true
    を使用すると、 import “./foo.css” など任意の拡張子をimportでき
    るようになる。
    https://github.com/microsoft/TypeScript/pull/51435

    View Slide

  15. ⑤ 任意の拡張子をimportするオプション
    TypeScript 5.0で追加される
    allowArbitraryExtensions: true
    を使用すると、 import “./foo.css” など任意の拡張子をimportでき
    るようになる。
    Q. 前からできたのでは?
    https://github.com/microsoft/TypeScript/pull/51435

    View Slide

  16. ⑤ 任意の拡張子を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

    View Slide

  17. 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

    View Slide

  18. Node.jsのES Modulesだと……
    Node.jsのESMだと拡張子を省略できない。
    import “./foo.css” ←型定義
    ???
    ↓別物↑
    import “./foo.css.js” ←型定義
    foo.css.d.ts

    View Slide

  19. Node.jsのES Modulesだと……
    Node.jsのESMだと拡張子を省略できない。
    import “./foo.css” ←型定義
    foo.d.css.ts
    ↓別物
    import “./foo.css.js” ←型定義
    foo.css.d.ts
    TypeScript 5.0で .d.ext.ts が導入される。
    CommonJS時代には真剣に考慮する必要がなかった拡張子に
    関するサポートを拡張した結果生まれた。

    View Slide

  20. 総評
    TypeScriptはこれまでモジュール解決をむやみに拡張可能にする
    のではなく、現実のユースケースに合致することを重視してきた。
    今回もその流れは変わらず、Node.jsでの非JSファイル読み込み
    やバンドラという具体的なユースケースを念頭においた機能追加
    だった。
    昔の独自路線(enumとか)を反省してか、TypeScriptは独自の
    仕様を作ったり普及させたりしないようにかなり気を付けている
    ように見える。

    View Slide

  21. 所感
    フロントエンド開発でpackage.jsonのexportsを使いたい際に
    ネックになるのがTypeScriptだったので、5.0でそこが解消され
    るのはとても嬉しい。
    デコレータも正式版が実装されたら設計に取り入れたい。
    おわり

    View Slide