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

ConstructorParameters<T>がクラスコンストラクタのパラメータ型をタプルとして抽出する方法を学びます。ファクトリ関数と依存性注入の例を紹介します。

Function Types

詳細な説明

ConstructorParametersの理解

ConstructorParameters<T>はコンストラクタ関数型のパラメータ型からタプル型を構築します。Parametersのコンストラクタ版です。

構文

type ConstructorParameters<T extends abstract new (...args: any) => any> =
  T extends abstract new (...args: infer P) => any ? P : never;

基本的な例

class ApiClient {
  constructor(
    public baseUrl: string,
    public timeout: number,
    public headers: Record<string, string>
  ) {}
}

type ClientArgs = ConstructorParameters<typeof ApiClient>;
// 結果: [baseUrl: string, timeout: number, headers: Record<string, string>]

実践パターン: デフォルト値付きファクトリ

function createWithDefaults<T extends new (...args: any[]) => any>(
  Ctor: T,
  defaults: Partial<Record<number, ConstructorParameters<T>[number]>>
): (...args: ConstructorParameters<T>) => InstanceType<T> {
  return (...args) => new Ctor(...args);
}

組み込み型との使用

type DateArgs = ConstructorParameters<typeof Date>;
// 結果: [value: string | number | Date](1つのオーバーロード)

type ErrorArgs = ConstructorParameters<typeof Error>;
// 結果: [message?: string, options?: ErrorOptions]

type RegExpArgs = ConstructorParameters<typeof RegExp>;
// 結果: [pattern: string | RegExp, flags?: string]

実践パターン: テストヘルパー

class UserService {
  constructor(
    private db: Database,
    private mailer: Mailer,
    private logger: Logger
  ) {}
}

type ServiceDeps = ConstructorParameters<typeof UserService>;
// [db: Database, mailer: Mailer, logger: Logger]

function createTestService(
  ...overrides: Partial<ServiceDeps>
): UserService {
  const defaults: ServiceDeps = [mockDb, mockMailer, mockLogger];
  const args = defaults.map((d, i) => overrides[i] ?? d);
  return new UserService(...(args as ServiceDeps));
}

ユースケース

ConstructorParameters<T>はファクトリ関数、依存性注入コンテナ、コンストラクタ引数をモックするテストヘルパー、クラスコンストラクタが何を期待するかを知る必要があるユーティリティの構築に使用します。

試してみる — TypeScript Utility Types

フルツールを開く