本セッションの登壇者
セッション動画
クレスウェア株式会社の奥野賢太郎です。私はTypeScriptが登場してすぐの2013年初頭から使っていますので、TypeScript歴はちょうど10年になります。今回はこの10年間のTypeScriptの進化について各バージョンで追加された機能や進化の傾向を振り返りつつ、今後のTypeScriptの学習/キャッチアップ方法についてもご紹介します。
TypeScriptは10歳 - 過去を振り返る
まずはTypeScriptの誕生から現在まで、過去10年間の各バージョンで追加された機能を振り返り、TypeScriptの進化の歴史をご紹介します。
TypeScript 0.8 - 1.0 (2012 - 2014)
TypeScriptは2012年10月1日生まれで、誕生から10年を超えました。TypeScriptはバージョン1.0ではなく0.8でパブリックになり、公開当時はunstable扱いでした。バージョン0.8でさまざまな意見を募り、0.9でそれらの意見を反映した改良/テストを行い、2014年4月2日に1.0がリリースされました。
登場初期の0.8→1.0の間にも大きな変化がありました。たとえばTypeScriptの配列は、0.8では単純なArray型として登場しましたが、その後Genericsがあったほうが良いという意見が多かったため、0.9ではArray型に改良されています。
TypeScript 1.x (2014 - 2016)
その後、TypeScript 1.xの時代が2014年から2016年の間続きます。このころは有志コミュニティのDefinitely Typedが型定義ファイル(.d.ts
)を保守していましたが、npmで管理していませんでした。そのため、型定義依存解決ツールを別途インストールする必要があり、面倒でした。ただ、この時期はTypeScriptが注目を集め始め、さまざまなライブラリの型定義ファイルが増えていったおもしろい時代でもあります。
TypeScript 2.x (2016-2018)
TypeScript 2.xではようやく型定義ファイルがnpmで管理されるようになりました。いまやあたりまえですが、1.xと比べると大きな進化でした。現在では、@types/something
を依存関係に追加しなくても、ライブラリなどの実装をインストールすれば一緒に型定義ファイルも付いてきたり、もともとの実装がTypeScriptで書かれていることも多くなり、型定義ファイルを別途インストールすることは少なくなりました。
また、--strictNullChecks
(undefined
とnull
の型の違いを区別する型チェック)オプションやnever
型(例外のときに扱う型)もTypeScript 2.xで導入されました。
TypeScript 1.x - 2.xでは下記の機能も導入され、TypeScriptの骨格を作った時代ともいえます。
- Tuple Types (1.3 / 2014):
[number, string]
- Union Types (1.4 / 2015):
number | string
- Type Guards (1.4)
- String Literal Types (1.8 / 2016)
- Mapped Types (2.1 / 2016)
- Conditional Types (2.8/2018)
TypeScript 3.x (2018 - 2020)
2.xでTypeScriptの骨格を作る新機能がぞくぞくと追加されたあと、2018年に3.xが登場します。さきほどのKuramiさんのセッションで「Typesafeを実現するにはunknown型をつぶす」というお話がありましたが、そのunknown型の概念が登場したのは3.xです。
なお、2.x - 3.xでのTypeScriptの進化については、私の2022年のアドベントカレンダーでいつどのような機能が登場したのか25日分の記事にまとめています。よろしければご覧ください。
TypeScript 4.x - 現代のバージョンになってから
ここまではバージョン3.xまでの過去のお話でしたが、4.xになってから現在までどのように進化してきたかをご紹介します。TypeScript 4.0が登場したのが2020年でしたので、すでに3年経っており、4.xの中でもさまざまな進化がありました。
TypeScript 4.1 (2020)
TypeScript 4.1以前でもさまざまなことが実現できるようになっていましたが、4.1ではTemplate Literal Typesという興味深い機能が導入されるなど、できることの幅がさらに広がりました。
文字列の型として4.1までstring型(ダブルクォートやシングルクォートで囲んだ文字列)がありましたが、Template Literal Typesではバッククォートで囲んだTemplate Literal内に別の型を入れられるようになりました。
たとえば下記のサンプルコードでは、\
hello ${World}``をGreeting型として定義していますが、波括弧で囲まれた部分には別のstring literal typeであるWorld型が入っています。
これを使うと、四角形の四隅を示す"top-left", "top-right", "bottom-left", "bottom-right"
のように決まった部分文字列を組み合わせてできる文字列を型として定義できます(TypeScript 4.1のリリースノートに具体的なサンプルがあります)。
ほかにもおもしろい使い方があり、Kuramiさんが型だけでひたすらプログラミングされている「TypeScript型パズルで作るmini interpreter」や、別の方の記事「TypeScriptの型定義で麻雀の役判定をする」など、TypeScriptの「型」に関する部分だけでも何らかの機能を実現することもできます。
また4.1ではRecursive Conditional Typesが追加され、これも実務で使うことがある機能です。Conditional Typesは条件に基づいて型を生成するものでしたが、Recursive Conditional Typesでは再帰(ある型の中で同じ型を呼び直す)ができます。これができるとPromiseの解決処理や、部分的にPartialにするRecursive Partial(私のアドベントカレンダー記事実例RecursivePartial<T>
で紹介しています)も実現できます。Recursive Conditional Typesが導入されたことで、よりプログラマブルな型定義ができるようになりました。
TypeScript 4.4(2021)
4.4で登場した機能のうち、実務に関連しそうなのは--useUnknownInCatchVariables
です。3.9まではcatch
ブロックでのerr
変数(例外)はany型でしたが、4.0からはオプショナルでunknown型扱いに、4.4からはデフォルトでunknown型扱いに変わり、例外の扱いがよりtype safeになりました。
TypeScript 4.7 (2022)
4.7では、Node.jsのESModuleに対応するコンパイルオプションが追加されました。このコンパイラオプションは、uhyoさんのセッションでもお話があった「5.0から拡張子.ts
によるimportが解禁される」ということにも関連しています。4.5から4.7にかけてはCJSやESM関連の対応が充実していますので、ぜひ調べてみてください(Kuramiさんの記事「TypeScript 4.7とNative Node.js ESM」で詳しく解説されています)。
TypeScript 4.9 (2022)
詳細は割愛しますが、satisfies Operatorという新概念が導入されており、鹿野壮さんの記事「TypeScript 4.9のas const satisfiesが便利。型チェックとwidening防止を同時に行う」や本日のセッションで詳しく解説されていますので、そちらをご覧ください。
進化の傾向
ここまでTypeScriptに追加された機能を振り返ってきましたが、TypeScriptの進化にどのような傾向があったかをお話します。
TypeScript 0.8から2.9までは怒涛の進化でした。バージョンがあがるたびに何らかの新機能が導入され、キャッチアップも大変でしたがその分実務で使える機能が充実し、おもしろい時代でした。
3.0以降は進化のスピードが緩やかになりましたが、かゆいところに手が届く進化が増え、できなかったことがようやくできるようになったり、「知っておくと業務上でちょっと助かる」という機能が増えたりしました。進化のスピードが緩やかになった分、キャッチアップしやすくなってきています。
おすすめの学習方法
TypeScript初学者の方は、0.8から5.0までで登場したすべての機能を学習する必要はなく、まず専門書を読むことをおすすめします。専門書には理解すべき機能・概念が網羅的に書いてあります。また、私のアドベントカレンダーでは業務上の工夫やノウハウをご紹介していますので、ぜひお読みください。
また今後はTypeScript自体のキャッチアップに加えて、周辺事情に幅広く興味を持つことをおすすめします。たとえばDenoやBunなどの新しいランタイム、ES2023/TC39などの言語仕様に追加された新しい機能や構文、モジュール事情、バンドル事情などを含めて、ぜひめげずにTypeScriptのキャッチアップを続けてください。
私の発表は以上です。ありがとうございました。