最近、React + Typescript しか書いてないので、久々に小ネタを投下しようかなっと。。。
tl;dr
- JavaScript でよくやる引数の
object = object || {}を、Typescript でコンパイルエラーを回避しながらどうやるか。
ユースケース
例えば、React でこのような stateless function components(以下、Book)を作ったとします。
Bookはインタフェースとして、bookを受け取ってnameを表示する非常に単純な component です。
interface IBook {
name: string;
}
interface IBookProps {
book: IBook;
}
export defaut function Book({ book }: IBookProps) {
return <div>{book.name}</div>
};
ところが、 bookは API から取得する必要があり、Bookを初期化されるタイミングではundefinedとなっています。
おそらく、bookをundefinedのまま、Bookに渡した場合は、次のようなエラーが発生するでしょう。
Uncaught TypeError: Cannot read property 'name' of undefined
ES6 Default parameters を使ってみる
早速、book = book || {}と行きたいのですが、ES6 のDefault parametersを使ってみます。
export defaut function Book({ book = {} }: IBookProps) {
return <div>{book.name}</div>
};
しかし今度は、 IBook型と一致しないというコンパイルエラーが出力されます。
error TS2322: Type '{}' is not assignable to type 'IBook'. Property 'name' is missing in type '{}'.
まぁ、当然ですね。
正しい Default parameters の使い方
{}には型を設定することができるので、Default parameters を設定するときに正しく型を指定してみます。
これで、コンパイルエラーを無事回避することができました。さらに IDE の補完も効きます。
export defaut function Book({ book = {} as IBook }: IBookProps) {
return <div>{book.name}</div>
};
まとめ
最初は、IBookを実装した、クラスを定義してダミーの値を設定しないと無理かと思っていましたが、型を設定することであっさり出来ました。
Typescript の intarface は定義するの少し面倒ですが、こういう場合に重宝するので、定義した方がいいですよー。
