TypeScript InstanceType详解

发布时间:2023-05-22

一、InstanceType是什么

在TypeScript中,InstanceType是一个泛型类型,它用于获取构造函数类型的实例类型。 示例代码:

class SomeClass {
  name: string;
  age: number;
}
type SomeClassInstance = InstanceType<typeof SomeClass>;
// SomeClassInstance的类型为 SomeClass

二、InstanceType的使用场景

InstanceType常用于泛型约束和提取类型信息。在初始化某个变量时,需要使用某个类的实例,InstanceType可以有效地约束泛型类型,避免了手动定义重复类型的问题。 示例代码:

class SomeClass {
  name: string;
  age: number;
}
function createInstance<T extends new (...args: any[]) => any>(
  ctor: T,
  ...args: ConstructorParameters<T>
): InstanceType<T> {
  return new ctor(...args);
}
const instance = createInstance(SomeClass, "Alice", 20);
// instance的类型为 SomeClass

三、InstanceType的局限性

InstanceType并不适用于所有构造函数类型,它仅能用于具有无参构造函数的类类型。 示例代码:

class SomeClass {
  name: string;
  age: number;
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}
type SomeClassInstance = InstanceType<typeof SomeClass>;
// 报错:Type 'SomeClass' does not satisfy the constraint 'new (...args: any) => any'.
// Type 'SomeClass' provides no match for the signature 'new (): any'

上述代码中因为SomeClass有构造函数,而该构造函数有参数,因此不能使用InstanceType获取其实例类型。

四、InstanceType的兼容性

当使用TypeScript 2.8以下版本时,如果存在引用外部库的class,无法使用InstanceType获取其实例类型。但是在TypeScript 2.8版本中,这个问题得到了解决。 示例代码:

class SomeClass {
  name: string;
  age: number;
}
type ExternalClass = typeof someLibrary.ExternalClass;
type SomeClassInstance = InstanceType<ExternalClass>;
// TypeScript 2.7及以下版本:报错
// TypeScript 2.8及以上版本:SomeClassInstance的类型为 ExternalClass 的实例类型

五、InstanceType与keyof的搭配使用

InstanceType还可以和keyof结合使用,用于获取对象中所有值类型的集合。 示例代码:

type SomeObject = {
  name: string;
  age: number;
  gender: "Male" | "Female";
};
type SomeValues = InstanceType<typeof SomeObject>[keyof InstanceType<typeof SomeObject>];
// SomeValues的类型为 string | number | "Male" | "Female"

六、小结

InstanceType是TypeScript提供的一个非常实用的泛型类型,它可以用于获取构造函数类型的实例类型,避免手动定义重复类型的问题。但是需要注意InstanceType并不适用于所有构造函数类型,只能用于具有无参构造函数的类类型。同时,使用时也需要注意TypeScript版本兼容性问题。