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

InstanceType<T>がクラスコンストラクタからインスタンス型を抽出する方法を学びます。ファクトリパターン、依存性注入、ジェネリッククラスユーティリティの例を紹介します。

Function Types

詳細な説明

InstanceTypeの理解

InstanceType<T>Tのコンストラクタ関数のインスタンス型から型を構築します。クラスコンストラクタ(typeof ClassName)を受け取り、new ClassName()が生成するものを返します。

構文

type InstanceType<T extends abstract new (...args: any) => any> =
  T extends abstract new (...args: any) => infer R ? R : any;

基本的な例

class Logger {
  level: "info" | "warn" | "error" = "info";
  log(msg: string): void {
    console.log(`[${this.level}] ${msg}`);
  }
}

type LoggerInstance = InstanceType<typeof Logger>;
// 結果: Logger(levelとlogを持つインスタンス型)

実践パターン: ジェネリックファクトリ

function createInstance<T extends new (...args: any[]) => any>(
  Ctor: T,
  ...args: ConstructorParameters<T>
): InstanceType<T> {
  return new Ctor(...args);
}

class Database {
  constructor(public url: string, public port: number) {}
}

const db = createInstance(Database, "localhost", 5432);
// 型: Database(anyではない)

抽象クラスとの使用

abstract class Shape {
  abstract area(): number;
}

class Circle extends Shape {
  constructor(public radius: number) { super(); }
  area() { return Math.PI * this.radius ** 2; }
}

type ShapeInstance = InstanceType<typeof Circle>;
// 結果: Circle

実践パターン: プラグインレジストリ

const plugins = {
  auth: AuthPlugin,
  cache: CachePlugin,
  logger: LoggerPlugin,
};

type PluginInstances = {
  [K in keyof typeof plugins]: InstanceType<typeof plugins[K]>;
};

ユースケース

InstanceType<T>はファクトリ関数、依存性注入コンテナ、プラグインシステム、インスタンス型を保持しながらクラスのインスタンスを動的に作成するジェネリックユーティリティに使用します。

試してみる — TypeScript Utility Types

フルツールを開く