TypeScriptは静的型付けを実現しているため、時には明示的にある型を別の型に変換する必要があります。たとえば、開発者がコンパイラよりもデータの構造をよく知っている場合や、期待される型と一致しない型付きのAPIを扱う必要がある場合です。これを実現するのが型キャスティング機構(または型アサーション)です。
TypeScriptにおける型キャスティングは、実行時に値の変換を行うものではありません。単にコンパイラに対して「私を信じて」と伝えるだけです。指定されたキャストがデータの実際の内容と一致しない場合、エラーが発生する可能性があります。このエラーは実行時にのみ発生し、コンパイラでは検出されません。
TypeScriptには、2つの型変換構文があります:角括弧構文(非推奨、JSXに対して)とas構文(推奨)です。
// 角括弧構文(.tsxには不適) let someValue: any = "Hello World"; let strLength: number = (<string>someValue).length; // as構文を使用 let strLength2: number = (someValue as string).length; // オブジェクトの型キャスティング(unsafe!) interface Cat { meow(): void; } interface Dog { bark(): void; } let dog: Dog = { bark() {} }; let cat = dog as unknown as Cat; // 可能だが、型付けを回避します!
型アサーションは、C#やJavaのようにランタイムで自動的に値を変換しますか?
いいえ、型アサーションは単にコンパイラに対して、その変数がその型であることを示します。値の変換は発生せず、責任は完全に開発者にあります。
共通の構造なしに型Aを型Bにキャストできますか?
TypeScriptはこれを許可します(例えばanyやunknownを介した二重キャストなど)、しかしこれは型の安全性を損なう可能性があり、実行時のエラーを引き起こす可能性があります。
const a = 5 as unknown as string; // 安全ではありません!
anyを複雑な型にキャストすることは安全ですか?
いいえ、anyは型検査を無効にします。anyから別の型への変換は可能ですが、TypeScriptは不一致を検出できず、いかなるエラーも実行時にのみ現れます。
開発者がサーバーから構造を検証せずにオブジェクトを受け取り、単純にas SomeTypeで期待される型にキャストします。そしてビジネスロジックで使用します。APIの変更やサーバーのバグにより、アプリケーションがランタイムでクラッシュし、ビルド時にはエラーが発生しません。
利点:
欠点:
開発者が受信したオブジェクトの構造を事前に検証し、ユーザー定義のタイプガード関数を使用し、成功した検証の後に型アサーションを行います。
利点:
欠点: