今日やったこと
- 「モダンJavaScriptの基本から始める React実践の教科書」 P231〜238
- 8-7 オプショナルチェイニング(Optional chaining)
- 8-8 ライブラリの型定義
学習メモ
オプショナルチェイニング(Optional chaining)
オプショナルチェイニングはTypeScript ver3.7で追加された機能で、
オブジェクト内のプロパティが存在するか否かを気にせず安全に処理してくれる仕組み
これまで作ってきたユーザー管理システムに「趣味」の項目を追加することになったケースを例にすすめていく
APIで受け取るデータが以下のように変更された
[
{
"id": 1,
"name": "主田",
"age": 24,
"personalColor": "blue"
},
{
"id": 2,
"name": "先岡",
"age": 28,
"personalColor": "pink"
},
{
"id": 3,
"name": "後藤",
"age": 23,
"personalColor": "green",
"hobbies": ["game", "soccer"]
},
]
user.tsにhobbies
をstringの配列型として追加
export type User = {
id: number;
name: string;
age: number;
personalColor?: string;
hobbies?: string[];
};
App.tsxにPropsを追加
// …省略
return (
<div>
{users.map(user => (
<ListItem
id={user.id}
name={user.name}
age={user.age}
personalColor={user.personalColor}
hobbies={user.hobbies}
/>
))}
</div>
);
};
ListItem.tsxにPropsを追加
※ 表示する際は配列に使用できるjoin
メソッドを使う(joinは()内で指定した文字で配列の要素を結合し1つの文字列とするメソッド)
// …省略
export const ListItem: FC<User> = props => {
const { id, name, age, personalColor, hobbies } = props;
return (
<p style="{{ color: personalColor }}">
{id}:{name}{(age)} {hobbies.join(" / ")}
</p>
);
};
これで機能の実装ができたように思えるが、
実行すると以下のようなエラーが表示されてしまう
Cannot read property 'join' of undefined
現在APIで取得したデータにはidが3の後藤にしかhobbies
が設定されておらず
その他のデータはhobbies
がundefinedでListItem.tsxに渡ってくる
その際undefinedにはjoin
というメソッドは使えないため、上記のようなエラーが表示されてしまう
Userの型定義的にはhobbies
に「?」をつけており
省略される可能性があるのは分かっているので、これをオプショナルチェイニングで解決する
オプショナルチェイニングは実装としては非常に簡単で、
省略されるかもしれないプロパティ名のあとに「?」をつけるだけ
ListItem.tsxでオプショナルチェイニングの実装
// …省略
export const ListItem: FC<User> = props => {
const { id, name, age, personalColor, hobbies } = props;
return (
<p style="{{ color: personalColor }}">
{id}:{name}{(age)} {hobbies?.join(" / ")}
</p>
);
};
- オプショナルチェイニングを指定することで、プロパティが存在しない場合は、その先は実行せずにその時点でundefinedを返却してくれる
- 型定義上「?」がついているプロパティの実装時は基本的にオプショナルチェイニングにしておけばOK
- 型定義をしている状態で「.」入力時にエディタが表示してくれる候補を選択すると自動で「?」を補完してくれたりするので便利
TypeScriptを使うと様々な箇所で意味の違う「?」が登場するので最初は混乱するかもしれないが、どれも必須の知識なので1つずつ順番に覚えていくと良い
ライブラリの型定義
これまでは自分の実装したコードに対する型定義について解説してきたが、
実際の開発の中では多くの外部ライブラリを使用することになるため、これらのライブラリの型定義の扱い方も知る必要がある
外部ライブラリの型定義に関しては、そのライブラリの対応状況に応じて3パターンに分かれる
パターン1:型定義がない
ライブラリが古かったりすると、そもそも型定義が存在しないライブラリもある
その場合は諦めてそのライブラリ周りのコードは型定義なしで使用するか、自分で作成することになる
型定義が存在するかどうかというのはTypeScriptプロジェクトでライブラリを設定する際の重要な指標となる
パターン2:ライブラリが型定義を包含している
そもそもライブラリ自体が型定義をデフォルトで持っている場合、通常通りnpmやyarnでライブラリをインストールすれば型が利いている状態で使用することが可能
「型定義を包含しているかどうか」というのはGitHubのリポジトリで〜.d.ts
ファイルを持っているかどうかで判断することができる
例えばaxiosではindex.d.ts
フォルダがあることが確認できるので、型定義を包含していることが分かる
パターン3:型定義を別でインストールする
Definitely Typedというリポジトリで様々なライブラリの型定義が管理されている
ここに型定義があるライブラリはnpmやyarnで @types/ ライブラリ名で型定義をインストールすることができる
例:react-router-domの場合(npm)
npm install -D @types/react-router-dom
例:react-router-domの場合(yarn)
yarn add -D @types/react-router-dom
Definitely Typedに型定義があるかどうか確認する手段としてはTypeScript公式のType Seacrhから探すか、npm(yarn) info @types/ ライブラリ名
をとりあえず実行して情報が返ってくるか確認するという方法もある
なお、TypeScriptのDefinitelyTypedは「ダメでもともと、うまく使えればラッキー」くらいの距離感がよいという話もある
所感
本書で学べるTypeScriptの基本的な使い方はここまでです。
あとは分からないところは調べながら進めていきます。
会社の方に教えていただいたのですが、
見切り発車でTypeScriptを使うことになった場合、以下のツールが便利そうでした。
急なTypeScript案件🔥最初の30日間に使い倒したい「コードリーディング支援ツール」
ツールのリンク先になっているサバイバルTypeScriptも、一通り読んでおきたいです。