TypeScript Required<T>ユーティリティ型の解説

Required<T>がPartial<T>の逆で、型のすべてのプロパティを必須にする方法を学びます。構文、例、厳密な型強制のユースケースを含みます。

Object Types

詳細な説明

Requiredの理解

Required<T>Tのすべてのプロパティを必須に設定した型を構築します。Partial<T>の逆で、すべてのプロパティからオプショナル修飾子(?)を削除します。

構文

type Required<T> = {
  [P in keyof T]-?: T[P];
};

-?構文はオプショナル修飾子を削除します。これは「マッピング修飾子の削除」と呼ばれるあまり知られていないTypeScriptの機能です。

基本的な例

interface Config {
  host?: string;
  port?: number;
  debug?: boolean;
  timeout?: number;
}

type StrictConfig = Required<Config>;
// 以下と同等:
// {
//   host: string;
//   port: number;
//   debug: boolean;
//   timeout: number;
// }

実践パターン: バリデーション済み設定

一般的なパターンは、ユーザーから部分的な設定を受け取り、デフォルト値を適用してから、完全に必須の型として扱うことです:

const defaults: Required<Config> = {
  host: "localhost",
  port: 3000,
  debug: false,
  timeout: 5000,
};

function createApp(userConfig: Config): App {
  const config: Required<Config> = { ...defaults, ...userConfig };
  // すべてのフィールドの存在が保証される
  console.log(config.host); // string(string | undefinedではない)
  return new App(config);
}

Pickとの組み合わせ

RequiredPickを使って特定のプロパティだけを必須にできます:

type WithRequiredId = Partial<User> & Required<Pick<User, "id">>;
// idは必須、それ以外はすべてオプショナル

ユースケース

Required<T>は、すべてのオプショナルプロパティがバリデーション済みまたはデフォルト値が設定済みで、すべてのフィールドの存在が保証される厳密な型が必要な場合に使用します。設定の解決、フォームバリデーションの結果、初期化後の状態型で一般的です。

試してみる — TypeScript Utility Types

フルツールを開く