TypeScriptのas(型アサーション)の概要と使いどころ

JavaScript

今回はTypeScriptの型アサーション(Type Assertion)について紹介します。利用するTypeScriptのバージョンは4.3.5です。

型アサーション(Type Assertion)とは

TypeScriptにはコードの周辺情報や文脈をもとに変数の型を推論する型推論(Type Inference)と呼ばれる機能があります。
TypeScriptがよしなに型を推論してくれるため、すべての変数や引数に対して型の定義をする必要がありません。

型アサーション(Type Assertion)はTypeScriptによって推論された型を上書きする機能です。変数を任意の型へ書き換えたい場合に型アサーションを利用します。

型アサーションの具体例

型アサーションの定義はas 指定したい型です。

型アサーションはas以外に<型>表記もありますが、<型>はJSX構文と区別しにくいという理由で非推奨のため説明を省略します。

たとえば以下のコードは型推論に頼るとコンパイルエラーになります。

interface Hoge {
  fuga: number;
  piyo: string;
}

let hoge = {}; // {}型に型推論される

hoge.fuga = 123; // Property 'fuga' does not exist on type '{}'
hoge.piyo = 'hello'; // Property 'piyo' does not exist on type '{}'

上記のコードに対して型アサーションを適用し、コンパイルエラーをなくしたものが以下になります。

interface Hoge {
  fuga: number;
  piyo: string;
}

let hoge = {} as Hoge; // Hoge型に型アサーションする

hoge.fuga = 123;
hoge.piyo = 'hello';

型アサーションのおかげで変数hogeHoge型として扱えるようになったため、コンパイルエラーが解消されました。

なお、明らかに正しくない型へは型アサーションを利用しても変更できません。

let fuga: number = 'hello' as number

// Conversion of type 'string' to type 'number' may be a mistake

型アサーションの注意点

型アサーションは任意の型に上書きができるため、型安全性が保証されなくなります。
つまり、型アサーションによる型に問題があった場合、コンパイルエラーとして検知されず、実行時に初めて気が付くことになります。

以下では型アサーションを利用する際に注意するべき具体例について紹介します。

適切でない型に気がつけない

以下のコードはコンパイルエラーにならず、実行時に初めてエラーがわかります。

let piyo = 'hello'
let fuga = piyo as any

// toPrecision() は指定された精度の文字列を返すnumber型のメソッド
console.log(fuga.toPrecision())

// [ERR]: fuga.toPrecision is not a function

fuga.toPrecision()を実行するためには変数fugaはnumber型でなければいけません。
しかし型アサーションを利用して変数fugaをany型へ変換すると、string型が代入されたことをコンパイル時に検知できなくなります。

オブジェクトのプロパティ忘れに気がつけない

型アサーションをオブジェクトの初期化に利用した場合、プロパティが足りなくてもコンパイルエラーになりません。

interface Hoge {
  fuga: number;
  piyo: string;
}

let hoge = {} as Hoge;
hoge.fuga = 123;

オブジェクトの初期化をするのであれば、型アサーションに頼るのではなく、以下のように型を明記するとよいです。

interface Hoge {
  fuga: number;
  piyo: string;
}

const hoge: Hoge = {
  fuga: 123
}; // Property 'piyo' is missing in type '{ fuga: number; }' but required in type 'Hoge'

型アサーションの使いどころ

型アサーションは『とりあえずコンパイルエラーを解決したい』という場合で利用します。
たとえば、JavaScriptからTypeScriptへの移行時の型エラーを解決するケースが型アサーションの利用例の1つです。

型アサーションは任意の型へ強制的に変更できるためコンパイルエラーを解消する強力な機能ですが、型安全性が保証されなくなります。
ですので、型アサーションはやみくもに利用するものではなく、コンパイルエラーを解消するための応急処置的な立ち位置だと認識しておくとよいです。

さいごに

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!

参考記事