
【Generics】TypeScriptの高度な型 ジェネリクスは? ② 関数の ジェネリクス
TypeScriptのジェネリクスを使うと、関数の型の決定を遅延することが出来ます。
元々、型を定義付けるのは、その変数や関数が、特定の型の値だけが付与されることを、
保証するものですが、
コーディングをしていると、型定義するときは、どんな型が欲しいかは保留にしておいて、
呼び出すときに型を指定してもらいたいという局面があるかもしれません。
では、どのように関数の型の決定を遅延させるのでしょうか?
実際に見ていきましょう。
【Generics】TypeScriptの高度な型 ジェネリクスは? ② 関数の ジェネリクス
function box<T>(props: T){ return {value: props} }
上記のように関数を定義します。
関数定義にジェネリクスが含まれていても、利用時の型指定は必須ではありません。
下記のように、ジェネリクスの指定を省略しても、引数に与えられた値から、型推論出来ます。
const box0 = box('test') const box1 = box(1) const box2 = box(true) const box3 = box(null)
アサーションによる明示的な型の付与
Nullable型などを直接適用したい場合、宣言時にアサーションを付与します。
const box2 = box(false as boolean | null) const box3 = box<string | null>(null)
関数を変数に代入する場合、下記のようにすることも可能です。
const boxed = <T>(props: T)=>({value: props})
extendsによる制約
変数と同様に、ジェネリクスにextendsシグネチャを付与することで、指定可能な型を制約できます。
function boxed<T extends string>(props: T){ return{ value: props} } const box1 = boxed(0) const box2 = boxed('test')
この制約により、関数内部に処理は型安全であることが保証されます。
次の例では、引数Props型を満たしていることが確約されているため、
props.amount(number 型)に備わっているtoFixed関数を実行できる。
interface Props { amount: number } function boxed<T extends Props>(props: T){ return {value: props.amount.toFixed(1) } } const box1 = boxed({amount: 0}) const box2 = boxed({value: 0}) //エラー、Props型を満たしてない const box3 = boxed({amount: 'test'}) //エラー、amountがnumber型ではない