(備忘録)Typescriptの型分析について
型ガード関数とは
Typescriptは型がないJavaScriptに型があるように振る舞うよう拡張された言語ですが、
しばしば外部のJSONファイルの読み込みや、外部サーバからのレスポンスオブジェクトなどどんな型なのか全く分からない値を扱う必要があります。
```typescript
const jsonFile = '{"key":"value"}';
const object = JSON.parse(jsonFile); // 型が分からずany型になる!
```
このままではany型(型なし)として振る舞ってしまうので型を分析して定義してあげる必要があります。
型分析をするには
- 型アサーション
- 型ガード
のどちらかで行うのが一般的です。
型アサーション
型アサーションは`as`キーワードを使った型の決めつけによる型分析です。
```typescript
const jsonFile = '{"key":"value"}';
const object = JSON.parse(jsonFile); // 型が分からずany型になる!
type Foo = {
key: string
}
const foo = object as Foo; // typeof foo is Foo
```
ただしこれはコンパイラを騙すものであり、型分析は一切行わないため危険なコードです。公式でも”アサーションは害”と言っています。
```typescript
const jsonFile = '{"key":"value"}';
const object = JSON.parse(jsonFile); // 型が分からずany型になる!
// Hoge型として解釈されてしまうがプロパティhogeは存在しない!
const hoge = object as Hoge; // typeof foo is Hoge
```
より安全に型分析を行うには型ガード関数を書く必要があります。
型ガード
より詳細に型分析を行うには型ガード関数を書く必要があります。
型ガード関数はユーザが定義した型構造に対して未知の値が満たしているかユーザが定義する関数で`is`キーワードを使います。
```typescript
const isFoo = (arg: any) : arg is Foo => {
const foo = arg is Foo;
return foo.key !== undefined;
}
```
この関数がtrueを返すとコンパイラがFoo型として解釈してくれるようになります。
型ガード関数の中で強引に型アサーションして各プロパティに値が格納されているか確認しています。
```typescript
const jsonFile = '{"key":"value"}';
const object = JSON.parse(jsonFile); // 型が分からずany型になる!
if(isFoo(object)) {
// ここではobjectはFoo型になる!
}
```
型ガード関数...プロパティがたくさんある型になるとそれだけ記述量が増えるし型の仕様が変われば合わせて型ガード関数を修正しないと行けないし、
オブジェクトが入子になっていたりユニオン型になっているととたんに型ガードの記述量増えるのでもっと上手に型分析する方法がある気がする。
型ガード関数の記述場所についても分からなかったので今後調べて追記したい。