🏄‍♂️

TypeScriptのバージョンを軽く振り返ってみた

2022/07/15に公開

はじめに

TypeScriptはMicrosoftによって開発されている、JavaScriptを拡張して作られたプログラミング言語です。
現在でもTypeScriptは改良を続けており、約3ヶ月に一回の頻度でバージョンアップがされています。
今ではいろんな現場で活躍しているTypeScriptですが、どのようなアップデートが行われてきたのか知らなかったので振り返ってみました。

ver1.0のリリース (2012/10)

TypeScriptがユーザーに公開されたのは2012年10月(ver0.8)でした。
言語として一通り体裁を整えてver1.0が2014年4月正式にリリースされました。

ver1.4 (2015/01)

ユニオン型

type StrOrNum = string | number // <= 2つ以上の型をパイプでつなぐ

type List = (string | number)[] // <= stringまたはnumberの配列を表現するときはこのように

また、ES6をターゲットにするモードも追加され、letやconst、テンプレートリテラルリテラルを使えるようになりました。

ver1.8 (2016/02)

リテラル型

type Hello = "Hello"

const foo: Hello = "Hello" // <= OK
const bar: Hello = "World" // <= NG

type CardinalDirection =
    | "North"
    | "East"
    | "South"
    | "West"

ver 2.0 (2016/09)

--strictNullChecksオプション

初期値にnullは許可されないよう設定することができるようになり、それに伴ってnullとundefinedが型として利用できるようになりました。

const str: string | null = "str"; // <= OK

const str: string = null; // <= NG

if文などの条件分岐による型の絞込み

function foo(value: string | number | boolean) {
    if (typeof value === "string") {
        return value // ここで返されるxはstring型
    }
    return value // ここで返されるxはnumber | booleanのユニオン型
}

readonly修飾子

readonlyをつけると読み取り専用のプロパティとして定義することができます。

interface Foo {
    readonly str: string;
}

let objA: Foo = {
    str: "TypeScriot",
};

// error TS2450: Left-hand side of assignment expression cannot be a constant or a read-only property.
objA.str = "JavaScript";

ver2.1 (2016/12)

keyof型

keyof型はオブジェクトからプロパティ名の型を得ることができます。

interface Person {
 name: string
 age: number
}

type PersonKey = keyof Person // <= 'name' | 'age' のユニオン型
type PersonName = Person['name'] // <= string型

Mapped types

Mapped typeはユニオン型からオブジェクトの型を作ってくれます

type Foo = { [P in "x" | "y"]: number } // <= { x: number, y: number }
type Bar = { [P in "x" | "y"]: P } // <= { x: "x", y: "y" }

ver2.8 (2018/03)

Conditional Types

三項演算子のように、ある条件を満たす時は型X、そうでなければ型Yを表すという表現が可能です。

type TypeName<T> = T extends string ? string : number

const str: TypeName<string> = "string"
const str2: TypeName<"a"> = "string"
const num: TypeName<number> = 2

ver3.0 (2018/07)

unknown型

any型と似ておりどんな値も代入することはできますが、別の具体的な型(string, number)への代入はできません。

const value: any = 10;
const int: number = value; // <= OK
const bool: boolean = value; // <= OK

const value: unknown = 10;
const int: number = value; // <= NG

また、unknown型のプロパティやメソッドにもアクセスすることはできません。

const value: unknown = "hoge"
console.log(value.slice(1)) // <= NG

const obj: unknown = { name: "オブジェクト" };
obj.name; // <= NG

ver3.7 (2019/11)

asserts型述語

asserts型述語は関数の返り値の型宣言として書かれ、その関数が例外を投げず終了したらその型であることを保証してくれます

function assertIsNumber(value: unknown): asserts x is number {
  if (typeof value !== "number") {
    throw new Error("value はnumberではありません");
  }
}

const unknownValue: unknown = "hoge";

assertIsNumber(unknownValue);// <= ここでsomeValueはnumber型になる

ver4.1 (2020/11)

テンプレートリテラル型

type Foo = 'Foo'
type Bar = 'Bar'

// 別の型にTemplate Literal を埋め込める
type FooBar = `${Foo} ${Bar}` // <=  FooBarは"Foo Bar"型となる

参考

https://github.com/Microsoft/TypeScript/
https://typescriptbook.jp/
https://js.studio-kingdom.com/typescript/
https://gihyo.jp/book/2022/978-4-297-12747-3

Discussion