首页 > 解决方案 > 如何指定类型是 TypeScript 中给定类类型的实例?

问题描述

我想创建一个Constructor将类作为类型参数并返回其构造函数签名的类型。

这对于在make可以创建该类的实例而不是使用new ClassInstance(...)语句创建它的类上定义静态属性方法很有用。

这是我到目前为止所得到的:

type ClassConstructorArgs<T> = T extends { new (...args: infer A): any }
  ? A
  : never;

type Constructor<T> = (...args: ClassConstructorArgs<T>) => T;

class Person {
  constructor(public name: string, public age: number) {}

  static make: Constructor<typeof Person> = (...args) => new Person(...args);
  //                                                     ^^^^^^^^^^^^^^^^^^^
  // Type 'Person' is missing the following properties from type 'typeof Person': prototype, make
}

问题是静态make有错误:Type 'Person' is missing the following properties from type 'typeof Person': prototype, make

我知道这是因为我的Constructor类型错误,类的构造函数T不返回类T本身,而是返回T.

但是我不知道如何表达Constructor返回的实例T而不是类T本身。这在 TypeScript 中是否可行?

标签: typescript

解决方案


Typescript 具有ConstructorParametersInstanceType的内置实用程序:

type Constructor<T extends new (...args: any) => any> = 
  (...args: ConstructorParameters<T>) => InstanceType<T>;

class Person {
  constructor(public name: string, public age: number) {}

  static make: Constructor<typeof Person> = (...args) => new Person(...args);
}

const p = Person.make('some name', 1); // p is of type Person

操场


如果您想知道这些实用程序是如何定义的,以及您的尝试有什么问题,请看这里:

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

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

资源


推荐阅读