メインコンテンツまでスキップ

型の絞り込み

TypeScriptには推論による型の絞り込み機能があります。これは以下のような機能です。

const a: string | number = 1

// aはstringかもしれないしnumberかもしれないのでこのままでは計算できない
a + 1 // ERROR!
a + "aaa" // ERROR!

// しかしtypeof演算子を用いて型を確認すれば
if (typeof a === "string") {
// aはstring型とわかる!
a + "aaa" // OK!
} else {
// aはnumber型とわかる!
a + 1 // OK!
}

これはトゥルーシーな値とフォルシーな値を絞り込んだりするのにも使える。

const a: { name: string } | undefined = {
name: "eraser"
}

a.name // ERROR!

// undefinedはフォルシーな値なので
if (a) {
// ifの中に入ったならそうではないとわかる!
a.name // OK!
}

他には、オブジェクト型AとBを明らかに区別することができるような方法があれば、以下のようなことも。

type A = {
__type: "A", // __を付けてるのは僕の好みです
hoge: string,
}

type B = {
__type: "B",
hoge: number,
}

const a: A | B = {
__type: "A",
name: "eraser",
}

// hogeはstring | number
a.hoge + "aaa" // ERROR!
a.hoge + 1 // ERROR!

if (a.__type === "A") {
a.hoge + "aaa" // OK!
} else {
a.hoge + 1 // OK!
}

TypeScriptバージョン4.6からは分割代入にも対応。それより前のバージョンでは型の絞り込みが正常に行えないので注意してください。

const { __type, hoge } = a

hoge + "aaa" // ERROR!
hoge + 1 // ERROR!

if (__type === "A") {
hoge + "aaa" // v4.6からはOK、それより前はERROR
} else {
hoge + 1 // 同上
}

また、switch文を通しての推論も可能。

const a: number | string | boolean = 1

switch (typeof a) {
case "number":
// aはnumber
break
case "string":
// aはstring
break
case "boolean":
// aはboolean
break
}