型の絞り込み
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
}