You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript:如何将typeof类类型转为实例类型并返回子类实例?

问题

给定类型typeof MyClass,如何将其转换为MyClass类型?

场景

在TypeScript中,你可以直接将类传入函数,并在函数内部创建该类的实例。

class MyClass {}

const init = (constructor: typeof MyClass): MyClass => {
  return new constructor()
}

// `myInstance` 的类型为 `MyClass`
const myInstance = init(MyClass)

但如果存在继承自父类的子类,该如何处理?

class Parent {}
class ChildA extends Parent {}
class ChildB extends Parent {}

const init2 = <T extends typeof Parent>(constructor: T) => {
  return new constructor()
}

// `childA` 和 `childB` 的类型为 `Parent`
// 期望 `childA` 的类型为 `ChildA`
// 期望 `childB` 的类型为 `ChildB`
const childA = init2(ChildA)
const childB = init2(ChildB)

如何设置init2的返回类型为所实例化的具体类类型?


解决方案

使用TypeScript内置的InstanceType<T>工具类型,它可以直接从构造函数类型T中提取对应的实例类型。修改init2的返回类型为InstanceType<T>即可:

class Parent {}
class ChildA extends Parent {}
class ChildB extends Parent {}

const init2 = <T extends typeof Parent>(constructor: T): InstanceType<T> => {
  return new constructor()
}

// 现在 `childA` 类型自动推导为 `ChildA`,`childB` 类型为 `ChildB`
const childA = init2(ChildA)
const childB = init2(ChildB)

原理说明

InstanceType<T>是TypeScript提供的工具类型,专门用于处理构造函数类型与实例类型的转换。当泛型T传入typeof ChildA时,InstanceType<T>会解析为ChildA类型,完全符合期望的具体子类类型。

扩展:处理带参数的构造函数

如果构造函数需要传入参数,可以结合ConstructorParameters<T>工具类型来确保参数类型匹配:

class Parent {}
class ChildA extends Parent {
  constructor(public name: string) {
    super()
  }
}

const initWithArgs = <T extends new (...args: any[]) => Parent>(
  constructor: T,
  ...args: ConstructorParameters<T>
): InstanceType<T> => {
  return new constructor(...args)
}

// 参数类型会自动校验,返回类型为ChildA
const childA = initWithArgs(ChildA, "Alice")

内容的提问来源于stack exchange,提问作者Nick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 23:41:12