型を絞り込んでアクセスしたい時や、型によって処理を分けたい時などに使用されるType Guardについてです。
typeof
const getData = (data: string | number): void => {
if (data.length > 0) { //string | number
console.log("string型:" + data); //string
} else {
console.log("number型:" + data); //number
}
};
getData関数の引数で入ってくるdataはstring型もしくはnumber型です。
if(data.length>0){}
この部分でstring型に絞りたいところですが、ts側からnumber型の可能性もあるよねっと言われてしまいます。
if文の中で使われているdataの型はまだnumber | stringの状態だからです。
上記のメソッドをtypeof
によるタイプガードを利用して実装してみます。
const getData = (data: string | number): void => {
if (typeof data === "string") { //string
console.log("string型:" + data); //string
} else {
console.log("number型:" + data); //number
}
};
if(typeof data = "string"){}
このif文でdataはstring型であると定義しているので、else文のdataは残りのnumber型だよねと推論してくれます。
ユーザー定義型のtypeGuard : parameterName is Type
type Fish = { swim: () => void };
type Bird = { fly: () => void };
const isFish = (pet: Fish | Bird): pet is Fish => {
return (pet as Fish).swim !== undefined;
}
parameterName is Type
parameterName が typeであればtrueを返し、そうでなければfalseを返します。
ただ注意しておきたいのが、以下のような関数の場合です。
const checkType = (value: string | number): value is string => {
return typeof value === "string";
};
const checkType = (value: string | number): value is string => {
return typeof value === "number";
};
checkType関数の場合value is string
とreturnのtypeof
で指定している型が矛盾しています。
ここの型が矛盾していてもtsではエラーが出ずにそのまま通ってしまいます。
value is string
とreturnのtypeof
で使用する型は、矛盾がないようにしないと予定していない処理が走ってしまいそうです。