Try   HackMD

「TypeScript」を語るフロントエンドTechCafe〜10周年おめでとう〜

はじめに

全体年表

年月 TypeScript 他トピック
2012/10 TypeScript 公開
2012/11 TypeScript 0.8.1 12月 ECMAScript 国際化 API 仕様の初バージョン
年月 TypeScript 他トピック
2013/01 TypeScript 0.8.2
2013/02 TypeScript 0.8.3
2013/06 TypeScript 0.9.0
2013/08 TypeScript 0.9.1
2013/12 TypeScript 0.9.5
年月 TypeScript 他トピック
2014/04 TypeScript 1.0
2014/11 TypeScript 1.3
2015/01 TypeScript 1.4 6月 ECMAScript 2015 公開
2015/07 TypeScript 1.5
2015/09 TypeScript 1.6
2015/11 TypeScript 1.7
年月 TypeScript 他トピック
2016/02 TypeScript 1.8 5月 TC39 proposals リポジトリに対する最初のコミット
6月 ECMAScript 2016 公開
2016/09 TypeScript 2.0
2016/12 TypeScript 2.1
年月 TypeScript 他トピック
2017/02 TypeScript 2.2 3月 TypeSciptを約2ヶ月ごとにリリースすることを宣言
3月 最初のTemporalプロポーザルの提案
2017/04 TypeScript 2.3 4月 Googleが社内の標準言語にTypeScriptを追加
2017/06 TypeScript 2.4 6月 ECMAScript 2017 公開
2017/09 TypeScript 2.5
2017/11 TypeScript 2.6
年月 TypeScript 他トピック
2018/02 TypeScript 2.7
2018/03 TypeScript 2.8 3月 TensorFlow.js: JavaScript による機械学習
2018/06 TypeScript 2.9 6月 ECMAScript 2018 公開
2018/07 TypeScript 3.0
2018/09 TypeScript 3.1 10月 CrateReactApp(雛型作成ツール)がTypeScript対応
2018/11 TypeScript 3.2
2018/02 TypeScript 3.3
年月 TypeScript 他トピック
2019/03 TypeScript 3.4
2019/06 TypeScript 3.5
2019/08 TypeScript 3.6 6月 ECMAScript 2019 公開
2019/11 TypeScript 3.7 CSS Containment Module Level 1がW3C勧告
年月 TypeScript 他トピック
2020/02 TypeScript 3.8 1月 CromiumベースEdge配信開始
2020/05 TypeScript 3.9 5月 VSCodeが複数のバージョンのTypeScriptの利用をサポート
6月 ECMAScript 2020 公開
2020/08 TypeScript 4.0 8月 ts-migrateリリース
2020/11 TypeScript 4.1
年月 TypeScript 他トピック
2021/02 TypeScript 4.2
2021/05 TypeScript 4.3 5月 JavaScript、宇宙に発射
5月 IEサポート終了を発表
6月 ECMAScript 2021 公開
2021/08 TypeScript 4.4
2021/11 TypeScript 4.5
年月 TypeScript 他トピック
2022/02 TypeScript 4.6
2022/05 TypeScript 4.7 6月 ECMAScript 2022 公開
6月 IEサポート終了
2022/08 TypeScript 4.8
2022/11 TypeScript 4.9

各バージョンの主要機能など

TypeScript 0.8.1

概要
  • 2回目のプレビュー
  • 最初のプレビュー以来、様々な提案やバグレポートが殺到。既存のJavaScriptライブラリのための型宣言ファイルが作成され始めているのを確認
  • 致命的なバグの修正
  • 最も要望の多かったソースレベルデバッグの追加
  • デバッグ機能
    • source map formatを用いたデバッグをサポート
    • JavaScript の出力に対応したソースマップファイルを出力する -sourcemap フラグを追加

TypeScript 0.8.2

概要
  • JSDocのサポート
  • Compile-on-Saveモードの追加
  • 様々な改善
    • デバッグ操作性の向上
    • 外部モジュールのコンパイル時に、出力先ディレクトリを指定できるようになった
    • jake(ビルドツール?)に移行

TypeScript 0.8.3

概要
  • コンパイラの改善
  • Visual Studio Debuggerの改善
    • Visual Studio がサポートする TypeScript のソースレベルデバッグでは、デバッグ対象のファイルが現在のプロジェクトの一部である必要がなくなりました。 これにより、Visual Studio は実行中の Internet Explorer のインスタンスにアタッチし、TypeScript プロジェクトをリモートでデバッグすることができる。
  • Visual Studio Editorの改善
    • コードにホバーした時の情報の見え方を改善?

TypeScript 0.9

概要
ジェネリクスの追加 例えばJavaScriptのmapに型をつけられるようになった
interface Array<T> {
    // ...
    map<U>(callbackfn: (value: T, index: number, array: T[]) => U): U[];
    // ...
}

var array: Array<string> = ["John", "Sam", "George"];

var lengths = array.map((val, idx, arr) => val.length); 

https://typescriptbook.jp/reference/generics

export = の追加
// client.ts 
    class Client { 
        constructor(public name: string, public description: string) { } 
    } 
    export = Client; 

    // app.ts 
    import MyClient = require('./client'); 
    var myClient = new MyClient("Joe Smith", "My #1 client");

TypeScript 0.9.1

概要
  • パフォーマンスの改善
    • 0.9リリースで落ちてしまったコンパイラのパフォーマンスを改善
  • typeof型演算子のサポート
  • No Implicit Anyオプションの追加
    • 変数が暗黙的にany型になる際にエラーとして処理できる

TypeScript 0.9.5

概要
  • メモリリーク、CPU使用率、クラッシュ、コンパイラの正しさなどに関する100以上の問題を修正
  • 200以上の.d.tsファイルが公開
  • ビルド時のメモリ使用量50%近く削減

TypeScript 1.0 ★

概要

1.0時点で実装されていた主な機能

TypeScript 1.3

protected修飾子の追加 自身のクラスとサブクラスからアクセス可能 [https://typescriptbook.jp/reference/object-oriented/class/access-modifiers](https://typescriptbook.jp/reference/object-oriented/class/access-modifiers)
turpleの追加 型が混在する配列の型を正確に記述できる
var tuple: [number, string] = [1, “bob”];
var secondElement = tuple[1];  // secondElement now has type ‘string’

TypeScript 1.4 ★

ユニオン型のサポート これまではユニオン型は関数のオーバーロードを使って表現していたが、より一般的に使えるようにした
function f(x: number | number[]) {
  if (typeof x === "number") {
    return x + 10;
  }
  else {
    // return sum of numbers
  }
}

ユニオン型 (union type)
インターセクション型 (intersection type)

Type Aliasesのサポート
type PrimitiveArray = Array<string|number|boolean>;
type MyNumber = number;
type NgScope = ng.IScope;
type Callback = () => void;

型エイリアス (type alias)
interfaceとtypeの違い

TypeScript 1.5

概要 - ES6のサポート - ES6モジュールのサポート
export function add(x, y) { return x + y }
export function subtract(x, y) { return x – y }
export default function multiply(x, y) { return x * y }

// myFile.ts

import {add, subtract} frommath”;
import times frommath”;
var result = times(add(2, 3), subtract(5, 3));
  • デコレータのサポート

TypeScript 1.6

概要
  • React/JSXのサポート
    • VS Codeでタイプチェックとオートコンプリート機能が使えるように
  • クラス式のサポート
class StateHandler extends class { reset() { return true; } } {
   constructor() {
     super();
   }
}

var g = new StateHandler();
g.reset();
  • ユーザー定義型ガード(is)の追加
  • インターセクション型&の追加
  • 抽象クラスのサポート
  • Type Aliasesでジェネリックが使えるようになった
type switcharoo<T, U> = (u: U, t:T)=>T;
var f: switcharoo<number, string>;
f(“bob”, 4);

TypeScript 1.7

概要
  • async/awaitのサポート
  • ポリモーフィックなthis型のサポート
  • moduleフラグで利用可能なオプションのリストにes6が追加
{
    “compilerOptions”: {
        “module”: “commonjs”,
        “target”: “es6”
    }
}

TypeScript 1.8

概要
  • モジュール拡張の追加
  • リテラル型の追加
  • より優れた制御フロー解析の実装
    • 到達しないコードの検出

      ​​​​​​​​function importantData() {
      ​​​​​​​​    return          // Automatic semicolon insertion triggered with newline
      ​​​​​​​​    {
      ​​​​​​​​        x: "thing"  // Error: Unreachable code detected.
      ​​​​​​​​    }
      ​​​​​​​​}
      
    • 暗黙的なreturnの検出

      ​​​​​​​​function isPizza(food) {   // Error: Not all code paths return a value.
      ​​​​​​​​    if (food === "pizza") {
      ​​​​​​​​        return true;
      ​​​​​​​​    }
      ​​​​​​​​    else if (food === "pie") {
      ​​​​​​​​        return true;
      ​​​​​​​​    }
      ​​​​​​​​    // implicitly returns `undefined`
      ​​​​​​​​}
      

TypeScript 2.0

null非許容型 --strictNullChecksオプションの指定でnullを許容しなくなる
var sample1: string = null; // error var sample2: string | null = null; // Unionでnull許容していればok
読み取り専用プロパティ readonly修飾子で読み取り専用プロパティを作成できる
class Sample { readonly a: string; constructor() { this.a = "sample"; // コンストラクタではOK } } var sample = new Sample(); sample.a = "sample2"; // error

TypeScript 2.1

keyof型 オブジェクトからプロパティをユニオン型として取り出せる

https://typescriptbook.jp/reference/type-reuse/keyof-type-operator

class Sample { a: string; b: number constructor() { this.a = "hoge"; this.b = 0; } } type Output = keyof Sample; // a | b のUnion相当
Mapped Types ユニオン型を元にオブジェクトの型を作成できる

https://typescriptbook.jp/reference/type-reuse/mapped-types

type PropertyList = "a" | "b"; type Sample = { [key in PropertyList]: string; }; var sample: Sample = { a: "hoge", b: "fuga", c: "test" // error }

TypeScript 2.2

Mix-in Mix-inをサポート

どのように実現するかはコードが長くなるので以下参照

https://typescript-jp.gitbook.io/deep-dive/type-system/mixins

※Mix-inとは簡単に言うと機能を複数のクラスで共有する仕組み・考え方

object型 プリミティブ以外を表すobject型の導入

Objectとは別 違い↓

https://typescriptbook.jp/reference/values-types-variables/object/difference-among-object-and-object

オブジェクトしか扱いたくないメソッドなどで誤ってプリミティブな値を渡してしまった際の検知が可能になった

TypeScript 2.3 ★

@ts-check ★

JSファイルでも@ts-checkを付与しておけばTypeScriptと同じように型チェックをしてくれる

https://devblogs.microsoft.com/typescript/announcing-typescript-2-3/#type-checking-in-javascript-files-withts-check-and-checkjs

エラーが出ても実行可能で、コードの変更なしにTypeScriptの恩恵を早期に受けることができるように(とりあえずチェックかけてみるといったことが可能)

TypeScript 2.4

Dynamic Import(非同期import) ECMAScriptの動的インポートへの追従

型チェックやトランスパイル・バンドルが機能するように対応

https://typescript-jp.gitbook.io/deep-dive/project/dynamic-import-expressions

文字列enum 列挙型の値に文字列を指定できるようになった(従来の未指定は数値)

結果に変化が出るので注意

enum NEWENUM { HOGE = "hoge", FUGA = "fuga" } console.log(NEWENUM.HOGE); // hoge console.log(NEWENUM["HOGE"]); // hoge enum OLDENUM { HOGE, FUGA } console.log(OLDENUM.HOGE); // 0 console.log(OLDENUM[0]); // HOGE
弱い型定義(プロパティがすべてオプショナル) 全てのプロパティがオプションの型を定義できるようになった

間違った引数を渡してしまった場合のエラー発見に役立つ

interface Sample { hoge?: string, fuga?: string } function someFunc(sample: Sample) { // any } var sample1 = { hoge: "hoge"; } var sample2 = { test: "test" } someFunc(req1); // OK someFunc(req2); // ERROR

TypeScript 2.5

例外処理でのcatch句の変数省略 エラー結果を使用しない場合にcatch句の変数を省略可能

JSへのトランスパイル時にダミーの変数が追加される

try { hoge(); } catch { // 例外情報を取得するための変数を省略 console.log("エラーになりました"); }

TypeScript 2.6 ★

https://qiita.com/vvakame/items/d2c7cf142fa0af39d2d5

@ts-ignore

@ts-ignoreを付与で型チェックのエラーを抑制

https://devblogs.microsoft.com/typescript/announcing-typescript-2-6/#error-suppression-comments-with-ts-ignore

JavaScriptからの移行中などTODO的に使うのはよいが乱用はほどほどに

TypeScript 2.7

https://qiita.com/vvakame/items/3a1e628e53a5dd99dfe0

初期化チェックの回避 変数末尾に`!`を付与することで変数の初期化を回避できる 初期化用のメソッドを使用する場合などで活用できる
class Sample { hoge: string; fuga!: string; constructor() { this.hoge = ""; // fugaを初期化しなくてもエラーにならない } }

TypeScript 2.8

Conditional Types 型定義における条件分岐を使用可能
type MyCondition<T, U, X, Y> = T extends U ? X : Y;

https://qiita.com/Quramy/items/b45711789605ef9f96de#conditional-types

TypeScript 2.9

特にめぼしいものがないのでスキップ

https://qiita.com/vvakame/items/0b22e5e34023e4c5d074

TypeScript 3.0

unknown型 型が何かわからないときに使う型

「型安全なany型」と言われ、よくany型と対比される

そのままでは他の型には代入できず、typeofやinstanceofで型を絞り込むことによって特定の型として扱えるようになる

https://typescriptbook.jp/reference/statements/unknown

TypeScript 3.1

特にめぼしいものがないのでスキップ

https://qiita.com/vvakame/items/dcd61bb1a600cf74c2bb

TypeScript 3.2

特にめぼしいものがないのでスキップ

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-2.html

TypeScript 3.3

特にめぼしいものがないのでスキップ(3.1あたりからUnionの変更が多め)

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-3.html

TypeScript 3.4

Faster subsequent builds incrementalフラグを立てることで、変更差分のみのコンパイルが可能

生成物のファイルハッシュが保存され、変更があった箇所のみリコンパイルする

(開発速度UP)

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html

TypeScript 3.5

特にめぼしいものがないのでスキップ(引き続きUnionが)

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-5.html

TypeScript 3.6

https://devblogs.microsoft.com/typescript/announcing-typescript-3-6/

Class Members Named "constructor" Are Now Constructors ECMAScript仕様に従って、名前付きのメソッドを含むクラス宣言は、
識別子名または文字列名を使用して宣言されているかどうかに関係なく、
コンストラクター関数になった。
    class C {
    "constructor"() {
        console.log("I am the constructor now.");
    }
}
JSDoc Comments No Longer Merge JSDocコメントが一部マージされなくなった。
@paramsを見るとargの型はstringになりそうだが、実際はanyで関数の直前に記載されたJSDocコメントが参照されている
/**
 * @param {string} arg
 */
/**
 * oh, hi, were you trying to type something?
 */
function whoWritesFunctionsLikeThis(arg) {
    // 'arg' has type 'any'
}

TypeScript 3.7

https://devblogs.microsoft.com/typescript/announcing-typescript-3-7/

Uncalled Function Checks 関数の呼び出しを忘れていたり、関数に引数がない場合に警告が出るようになった
interface User {
    isAdministrator(): boolean;
    notify(): void;
    doNotDisturb?(): boolean;
}

// later...

// Broken code, do not use!
function doAdminThing(user: User) {
    // oops! isAdministratorの呼び出しを忘れている
    if (user.isAdministrator) {
        sudo();
        editTheConfiguration();
    }
    else {
        throw new AccessDeniedError("User is not an admin");
    }
}
Optional Chaining オプショナルチェーン「?.」は、オブジェクトのプロパティが存在しない場合でも、
エラーを起こさずにプロパティを参照できる安全な方法。
const book = undefined;
const title = book?.title;
//                ^^オプショナルチェーン
console.log(title);
undefined
 
const book = { title: "サバイバルTypeScript" };
const title = book?.title;
console.log(title);

サバイバルTS:https://typescriptbook.jp/reference/values-types-variables/object/optional-chaining

TypeScript 3.8

https://devblogs.microsoft.com/typescript/announcing-typescript-3-8/

export * as ns Syntax 別モジュールのすべてのメンバーをまるっとエクスポートするのを 1 行で書けるようになった
// Before 
import * as utilities from "./utilities.js";
export { utilities };
// After
export * as utilities from "./utilities.js";

cyokodogBlog:https://www.cyokodog.net/blog/typescript-v3-8/

TypeScript 3.9

https://devblogs.microsoft.com/typescript/announcing-typescript-3-9/

// @ts-expect-error Comments コメントがついている行のエラーが報告されなくなり、エラーの詳細を伝えてくれる。
function doStuff(abc: string, xyz: string) {
    assert(typeof abc === "string");
    assert(typeof xyz === "string");

    // do some stuff
}

expect(() => {
    ///123でエラーが出てしまう
    doStuff(123, 456); 
//          ~~~
// error: Type 'number' is not assignable to type 'string'.
}).toThrow();

expect(() => {
  // @ts-expect-error
  doStuff(123, 456); // OK
}).toThrow();

zenn:https://zenn.dev/hedrall/articles/6f94763fc6a1cc

TypeScript 4.0

https://devblogs.microsoft.com/typescript/announcing-typescript-4-0/

Variadic Tuple Types タプル型の中にスプレット構文で記載することが出来る
type Repeat2 &lt;T extends readonly any[]&gt; = [...T, ...T];

// type SNSN = [string, number, string, number]
type SNSN = Repeat2&lt;[string, number]&gt;;
// type BSNSNB = [boolean, string, number, string, number, boolean]
type BSNSNB = [boolean, ...SNSN, boolean]
Short-Circuiting Assignment Operators 新しく代入演算子が追加された。
  • &&=
  • ||=
  • ??=

TypeScript 4.1 ★

https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/

Template Literal Types ★ 文字列を解釈して型定義ができる。文字列は変数化させて、テンプレートリテラルで埋め込める。

テンプレートリテラルで出来ること

  • 改行をそのままで記載
// 今まで
const before  = '1行目の文' +
'2行目の文' +
'3行目の文';
//テンプレートリテラル使用時
const after  = `1行目の文
2行目の文
3行目の文`;
  • タグ付きテンプレート
const id = 1;

// ログ結果your ID = 1
console.log(your ID = ${id}`) //idをバインド
console.log(your ID = ${id + 1}`) //任意の式を埋め込める
  • Template Literal公式使用例
function setVerticalAlignment(location: "top" | "middle" | "bottom") {
  // ...
}
 
setVerticalAlignment("middel");
Argument of type '"middel"' is not assignable to parameter of type '"top" | "middle" | "bottom"'.

MDN公式:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals
zenn:https://zenn.dev/mizchi/articles/template-literal-types-for-unit
typescript v4.2 beta:https://devblogs.microsoft.com/typescript/announcing-typescript-4-2-beta/

TypeScript 4.2

https://devblogs.microsoft.com/typescript/announcing-typescript-4-2/

Smarter Type Alias Preservation TypeScriptの内部では一つ以上の共用型で構成される共用型のとき、これらを1次元の共用型に変換しているので、Type Aliasを使用した関数で他の型もreturnで返した場合は、ホバー時にまとめて表示されてしまっていた。
export type BasicPrimitive = number | string | boolean;

export function doStuff(value: BasicPrimitive) {
    if (Math.random() &lt; 0.5) {
        return undefined;
    }
    return value;
}
// 今までvalusにホバーした場合は、string | number | boolean | undefinedになっていた
Reverting Template Literal Inference 末尾に as constをつけた場合は Template Literal Types になるように変更された。
const n: number = 123;

// value1 は string 型
const value1 = `${n}px`;  

// value2 は string 型
let value2 = `${n}px`; 

// value3 は `${number}px` 型
const value3 = `${n}px` as const;

zenn:https://zenn.dev/ak/articles/3e1a9b012b3c84

TypeScript 4.3

https://devblogs.microsoft.com/typescript/announcing-typescript-4-3/

Separate Write Types on Properties getterとsetterで異なる型を指定できるようになった。
class Thing {
    #size = 0;

    get size(): number {
        return this.#size;
    }
    // OK
    set size(value: string | number) {
        this.#size = typeof value === 'string' ? parseInt(value) : value;
    }
}
  • Template String Type Improvements

TypeScript 4.4

https://devblogs.microsoft.com/typescript/announcing-typescript-4-4/

Control Flow Analysis of Aliased Conditions 型ガードであるType Guardによる条件分岐の型絞り込みで変数に代入すると絞り込みがされるようになった。
function foo(arg: unknown) {
    // letの場合はエラーが出る
    const argIsString = typeof arg === "string";
    if (argIsString) {
        // We know 'arg' is a string now.←今まではエラーだった
        console.log(arg.toUpperCase());
    }
}

TypeScript 4.5

https://devblogs.microsoft.com/typescript/announcing-typescript-4-5/

The Awaited Type and Promise Improvements Awaited型が追加されawait,async関数の操作をモデル化できるようになった。
(型Typeを得る型関数)
// A = string
type A = Awaited<Promise<string>>;
// B = number
type B = Awaited<Promise<Promise<number>>>;
// C = boolean | number
type C = Awaited<boolean | Promise<number>>;

  • es2022がコンパイルモジュールとして使えるようになった

TypeScript 4.6

https://devblogs.microsoft.com/typescript/announcing-typescript-4-6/

Allowing Code in Constructors Before super() super()の前に処理を書いてもエラーにならなくなった
class Base {
    // ...
}

class Derived extends Base {
    someProperty = true;

    constructor() {
        // error!
        // have to call 'super()' first because it needs to initialize 'someProperty'.
        doSomeStuff();
        super();
    }
}

TypeScript 4.7

https://devblogs.microsoft.com/typescript/announcing-typescript-4-7/

ECMAScript Module Support in Node.js
  • .mts/.ctsという拡張子が増えた
  • ESM / CJS ごとに型定義を読み分けられるようになった
  • moduleDetectionオプションの追加
Optional Variance Annotations for Type Parameters outとinのアノテーションをつけることで、Tが入力と出力のどちらの型で使われるのかを明示することができるうようになった
interface Animal {
    animalStuff: any;
}

interface Dog extends Animal {
    dogStuff: any;
}

// ...

type Getter<T> = () => T;

type Setter<T> = (value: T) => void;

TypeScript 4.8

https://devblogs.microsoft.com/typescript/announcing-typescript-4-8/

Errors When Comparing Object and Array Literals オブジェクトや配列の比較で演算子の==や===を使うとエラーになるようになった
if (someArray === []) foo();
 // ~~~~~~~~~~~~~~~~~ エラーになる。    
Improved Intersection Reduction, Union Compatibility, and Narrowing {}オブジェクト型の挙動が改善された。{} | null | undefined型の変数にunknown型の変数が代入できるようになった。
function f(x: unknown, y: {} | null | undefined) {
    x = y; // always worked
    y = x; // used to error, now works
}

Typescript 4.9 ★

https://devblogs.microsoft.com/typescript/announcing-typescript-4-9/

The satisfies Operator★
式の結果の型を変更することなく、式の型がある型と一致するかどうかを検証できる

type Colors = "red" | "green" | "blue"; type RGB = [red: number, green: number, blue: number]; const palette = { red: [255, 0, 0], green: "#00ff00", bleu: [0, 0, 255] // ~~~~ The typo is now caught! } satisfies Record<Colors, string | RGB>; // Both of these methods are still accessible! const redComponent = palette.red.at(0); const greenNormalized = palette.green.toUpperCase();

https://zenn.dev/luvmini511/articles/55ad71c1ae99ba


  • 未使用のimportを自動で削除、既存のimportをsortしてくれるようになった