🏄♂️
TypeScriptのバージョンを軽く振り返ってみた
はじめに
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"型となる
参考
Discussion