TypeScript 07 ユーティリティ型

更新日:

TypeScript に最初から入っている「型を変形する道具」。import 不要でどこでも使える。

例に使う型:

type User = { id: string; name: string; email?: string; age: number }

オブジェクトを変形する

型効果例・使い所
Partial<T>全部を省略可能に更新処理の入力 update(id, patch: Partial<User>)
Required<T>全部を必須に既定値を埋めた後の設定
Readonly<T>全部を読み取り専用に変更させたくない state・設定
Pick<T, K>指定したキーだけ残すPick<User, 'id' | 'name'> 一覧表示用
Omit<T, K>指定したキーを除くOmit<User, 'id'> 新規作成の入力(id はサーバーが付ける)
Record<K, V>キー K・値 V のオブジェクトRecord<Status, string> ステータスごとのラベル
type Status = 'draft' | 'published'
const LABEL: Record<Status, string> = { draft: '下書き', published: '公開' }
// Status に 'archived' を足すと、LABEL に書き漏れがあるとエラー → 網羅性が保てる

⚠️ Omit は存在しないキーを指定してもエラーにならない(綴り間違いに注意)。

ユニオンを変形する

型効果例
Exclude<U, X>U から X に当てはまるものを除くExclude<'a' | 'b' | 'c', 'a'> → 'b' | 'c'
Extract<U, X>U から X に当てはまるものだけExtract<Result, { status: 'error' }>
NonNullable<T>null と undefined を除くNonNullable<string | null> → string

関数から取り出す

型効果
ReturnType<F>関数の返り値の型
Parameters<F>引数の型(タプル)
ConstructorParameters<C> / InstanceType<C>クラスのコンストラクタ引数 / インスタンスの型
Awaited<T>Promise を剥がした中身(入れ子も)
ThisParameterType / OmitThisParameter / ThisTypethis 関連(使用頻度は低い)
async function getUser() { return { id: '1', name: '山田' } }
type U = Awaited<ReturnType<typeof getUser>>   // { id: string; name: string }
type Args = Parameters<typeof setTimeout>      // setTimeout の引数タプル

その他

型効果
NoInfer<T>その位置から型推論させない(TS 5.4)
Uppercase / Lowercase / Capitalize / Uncapitalize文字列リテラル型の変換

組み合わせの実例

// 新規作成フォーム: id を除き、email 以外は必須
type CreateUserInput = Omit<User, 'id'>
// 更新: id は必須、他は任意
type UpdateUserInput = Pick<User, 'id'> & Partial<Omit<User, 'id'>>
// コンポーネントの props を他から流用
type ButtonProps = React.ComponentProps<'button'> & { variant?: 'primary' | 'ghost' }

型をどこから作るか(信頼できる情報源を1つに)

  • DB スキーマ(Drizzle / Prisma)や Zod スキーマ、GraphQL Codegen から型を生成・導出し、手書きの重複を減らす
  • 例: type User = z.infer<typeof UserSchema> / typeof users.$inferSelect(Drizzle)
  • 関連: GraphQL_05_実装ガイド(Codegen・Apollo・Relay・gql.tada)(Codegen で型を生成)

関連