呼び出しのたびに完全な型の精度を保つ、再利用可能な関数と型を書きましょう。
このレッスンを Kodokon で開くあなたはすでに、気づかないうちにジェネリクスを使っています。string[]、Promise<number>……。自分で書いてみるときが来ました。ジェネリクスは型パラメータを導入します。これは使うたびに具体的な型に置き換えられる変数です。目的は、型の精度を犠牲にせず、ロジックを一度だけ書くことです。
function first<T>(items: T[]): T | undefined {
return items[0];
}
const n = first([10, 20, 30]);
const s = first(["a", "b"]);呼び出し側では何も指定しなかったことに注目してください。TypeScript は引数から T を推論します。制約のないジェネリクスは何でも受け入れますが、関数はしばしばデータについて最低限の保証を必要とします。extends キーワードは T に最小限の形を課します。
interface HasId {
id: number;
}
function findById<T extends HasId>(
items: T[],
id: number
): T | undefined {
return items.find((item) => item.id === id);
}型自身もジェネリックにできます。これはネットワークコードの日常です。レスポンスの構造は安定していて、変わるのは data の中身だけ。すると1つの型が、あなたのすべての API レスポンスを記述します。
interface ApiResponse<T> {
ok: boolean;
data: T;
}
type UserResponse = ApiResponse<{ name: string }>;
const res: UserResponse = {
ok: true,
data: { name: "Ada" },
};