TypeScriptにはよくあるケースに合わせて型を用意したり、型を変換したりできる組み込みの型があります。TypeScriptに慣れた開発者のライブラリを読む時などイディオムの様によく使われているので都度参照できると便利です。
公式の紹介ページは次です。散逸していますが日本語でも多くの情報があります。
Utility Types · TypeScript
わかりやすく使いやすいものに次の二つがあります。
// @see https://www.typescriptlang.org/docs/handbook/utility-types.html#partialt
// 各プロパティ全てを任意パラメータ(undefinedでもOK)にします。
interface Todo {
title: string;
description: string;
}
function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
return { ...todo, ...fieldsToUpdate };
}
const todo1 = {
title: 'organize desk',
description: 'clear clutter',
};
const todo2 = updateTodo(todo1, {
description: 'throw out trash',
});
// @see https://www.typescriptlang.org/docs/handbook/utility-types.html#requiredt
// 各プロパティ全てを必須パラメータ(undefinedはNG)にします。
interface Props {
a?: number;
b?: string;
};
const obj: Props = { a: 5 }; // OK
const obj2: Required<Props> = { a: 5 }; // Error: property 'b' missing
この二つはweb系でAPI等のリクエストの形式を型で決定する際に便利です。作成時ならば全て必須、更新時ならばいずれも未定義でもOK、といった具合です。
またよく目にするものに次のRecordがあります。開発者に大きな裁量を与えるライブラリで特によく見ます。
// @see https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkt
interface PageInfo {
title: string;
}
type Page = 'home' | 'about' | 'contact';
// 第一引数の型をkey、 第二引数の型をvalueに取るオブジェクトの型を定義します。連想配列っぽい感じです
const x: Record<Page, PageInfo> = {
about: { title: 'about' },
contact: { title: 'contact' },
home: { title: 'home' },
};
const y: Record<number, PageInfo> = {
// about: { title: 'about' }, // stringをキーに持つとNG
3 : { title: 'three' } // numberをキーに持つならばOK
};
連鎖的に定義された型ですとこれらの組み込みの型を何度も経由してパズルの様になっていることがあります。都度調べられる様、思い浮かべられる様になると便利です。