TypeScriptは、JavaScriptの拡張として静的型付けのメリットを提供します。静的型付けにより、ソースコードから生成されたプログラムを実行する前に、型に基づく潜在的な問題を静的に検出できます。これにより、安全性が向上し、コードの可読性も高まります。
関数を定義する際、TypeScriptではよく引数と返り値に型を付けます。よく見ることになる何かの入口と出口にだけ型をつけて、なるべく型推論に任せるのが楽をしつつTypeScriptの良さを享受するコツです。以下に関数に型を付けた一例を示します。
type Schedule = { scheduleId: string; scheduleName: string; description: string; startAt: Date; endAt: Date; }; function updateScheduleDescription(baseSchedule: Schedule, newDescription: string): Schedule { // 関数の処理本体 }
型を付けることでTypeScriptが型による静的検査が行われ、実際にソースコードを元にしたプログラムを動かす前に問題点が把握できます。
上記例の型のつけ方は比較的扱いやすくベターなのですが、これでは取り回しがし難い時があります。これは Schedule の全てが必要でないこともままあるためです。上記例では Schedule 全体を型として定義していますが内部実装によっては一部のみでよく、不必要なプロパティを要求してしまっている場合もあります。この場合であるとして、プロパティについてよりシェイプアップさせたコードは次の様になります。
function updateScheduleDescription< // extends とジェネリクスを使うことで extends した部分を含む型ならなんでも引数に取れて、その型を返すと示す T extends { // IDと元となる説明文だけあれば十分 scheduleId: string; description: string; } >(baseSchedule: T, newDescription: string): T { // 関数の処理本体 } // 使用例 const oldSchedule = { hoge: 'fuga', description: 'foo', scheduleId: 'XBAJS3M', }; const newSchedule = updateScheduleDescription(oldSchedule, 'bar');
関数で使っている型のみを書いた必要最低限のパターンです。これにより Schdule の一部分のみを持つ値でも updateScheduleDescription 関数を使える様になりました。とはいえ、この状態では元の Schedule 型の scheduleId や description の型が変わった際にベタ書きのジェネリクスの extends 元に書いた部分の型も書き直す必要があります。これはいささか手間です。これを解決するためにユーティリティ型(TypeScript組み込みのある型から別の型を導き出してくれる型)の Pick が使えます。
Pick
Pickは、指定した型の一部のプロパティのみを抽出して新しい型を作成します。Pickを使用すれば、元の型が変更されても抽出した型が自動的に追従します。さらに、関数の引数や返り値がPickを使用して定義されている場合、その型が元の型の一部であることが明確になります。Pick を使った場合は次の様になります。
type Schedule = { scheduleId: string; scheduleName: string; description: string; startAt: Date; endAt: Date; }; function updateScheduleDescription< // Pick<Pick元の型, '抜き出したいプロパティA' | '抜き出したいプロパティB' | ...> と書く T extends Pick<Schedule, 'scheduleId' | 'description'> >(baseSchedule: T, newDescription: string): T { // 関数の処理本体 }
こうすることで、updateScheduleDescription関数はSchedule型のscheduleIdとdescriptionプロパティのみを必要とするようになります。Schedule型が変更されても、この関数の型は自動的に更新されます。
このように、TypeScriptのPickユーティリティ型を使用することで、型の一部のみを取り出して利用し、コードの可読性と安全性を向上させることができます。これにより、関数の定義や利用がより柔軟で効率的になります。