モジュールのレッスン (1/2)
タイプガード
型の絞り込みは、TypeScript の最も重要な概念の 1 つです。ただし、typeof や instanceof などの標準の型ガードでは、複雑なカスタム オブジェクトには不十分なことがよくあります。ここで カスタム タイプ ガード が役に立ちます。
標準タイプのガード
まずは、TypeScript が標準の JavaScript 演算子を使用して型を絞り込む方法を要約します。
function processInput(val: string | number) {
if (typeof val === 'string') {
// Here 'val' is of type string
console.log(val.toUpperCase());
} else {
// Here 'val' is of type number
console.log(val.toFixed(2));
}
}カスタム タイプ ガード (is 演算子)
カスタムの型ガードを定義するには、標準のブール戻り値の型の代わりに、型述語を parameterName is Type 形式で返す関数を作成します。
関数はブール値 (true または false) を返す必要があります。 true が返された場合、TypeScript は渡されたパラメーターが指定された型であることを認識します。
interface Cat {
name: string;
meow(): void;
}
interface Dog {
name: string;
bark(): void;
}
// This is a custom type guard
function isCat(animal: Cat | Dog): animal is Cat {
return (animal as Cat).meow !== undefined;
}
function makeNoise(pet: Cat | Dog) {
if (isCat(pet)) {
// Here TypeScript knows 'pet' is a Cat
pet.meow();
} else {
// Here TypeScript knows 'pet' is a Dog
pet.bark();
}
}安全性とキャスト (as とタイプ ガード)
型キャスト (val as Cat など) は、実際の実行時検証を行わずに、コンパイラーに開発者を信頼することを強制します。ランタイム オブジェクトが期待を満たさない場合、コードは通知なしで失敗するか、例外をスローします。
一方、カスタム型ガードは、堅牢かつ動的なランタイム チェックを実行し、TypeScript コンパイラーに実際の変数の型を安全かつ正確に通知します。
function processInput(input: unknown) {
// unsafe casting: could crash if input does not have the split method
// const str = input as string;
// console.log(str.split(' '));
// safe guard
if (isString(input)) {
console.log(input.split(' ')); // 100% Safe!
}
}自分で試してみてください
演習 1: 文字列型ガード
不明な値が文字列であるかどうかを確認するカスタム タイプ ガードとして機能する isString という名前の単純な関数を作成します。
ヒントを表示
関数の戻り値の型は val is string である必要があり、typeof を使用してそれが 'string' に等しいかどうかを確認する必要があります。
3 回の試行後に解決策が利用可能になります
演習 2: プレミアム ユーザー タイプ ガード
User タイプと PremiumUser タイプを指定して、ユーザーが「プレミアム」ロールを持っているかどうかを確認するタイプ ガード関数 isPremiumUser(user: User): user is PremiumUser を作成します。
ヒントを表示
署名を関数 isPremiumUser(user: User): user is PremiumUser として定義し、user.role を「premium」と比較します。
3 回の試行後に解決策が利用可能になります
演習 3: カスタム エラー オブジェクトの検証
isCustomError(err:unknown):err は、不明な値が「code」キーを含む null 以外の CustomError オブジェクトであるかどうかを検証する CustomError 関数です。
ヒントを表示
まず、typeof err が 'object' であり、null ではないかどうかを確認し、次に 'in' 演算子を使用して 'code' プロパティを確認します。
3 回の試行後に解決策が利用可能になります
演習 4: 管理者タイプ ガード
User (プロパティ role: string) と Admin (User を拡張し、プロパティ adminToken: string を持つ) という 2 つのインターフェイスがある場合、User 型のユーザーを受け入れ、型述語 user is Admin を返す isAdmin という名前の型ガード関数を作成します。ガードは、ユーザーのロールが「admin」と等しいかどうかを確認する必要があります。
ヒントを表示
署名を関数 isAdmin(user: User): user is Admin として定義し、user.role === 'admin' かどうかを確認します。
3 回の試行後に解決策が利用可能になります