Cover image for Typescript+ReactでDefault parametersにObjectを正しく設定する方法
reacttypescript

Typescript+ReactでDefault parametersにObjectを正しく設定する方法

October 05, 2016

3 min read

mitsuruogMitsuru Ogawa

最近、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となっています。

おそらく、bookundefinedのまま、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 は定義するの少し面倒ですが、こういう場合に重宝するので、定義した方がいいですよー。