在抽象类构造函数中获取子类型

Get child type in abstract class constructor

提问人:heavygl0w 提问时间:11/12/2023 最后编辑:heavygl0w 更新时间:11/13/2023 访问量:47

问:

我有一个抽象类,它将获取传递到构造函数的任何数据并将其分配给实例。目标是您可以使用实例的数据子集初始化实例。

我遇到的问题是,一旦扩展了抽象类,子类构造函数就需要一个 type 而不是 .Partial<AbstractParent>Partial<Child>

我已经能够使用静态创建方法、泛型和参数的使用来模仿这种模式,但我更希望能够使用构造函数来做到这一点。this

最小可重复示例

interface ResourceConstructor {
  new(data: Partial<Resource>): Resource

  create<T extends ResourceConstructor>(this: T, data: Partial<InstanceType<T>>): InstanceType<T>;
}

abstract class Resource {
  public abstract id: number;

  constructor(data: Partial<Resource>) {
    Object.assign(this, data);
  }

  static create<T extends ResourceConstructor>(this: T, data: Partial<InstanceType<T>>): InstanceType<T> {
    const instance = new this(data) as InstanceType<T>;
    return instance;
  }
}

class MyResource extends Resource {
  id: number = 1;
  someField: string = 'value';
}

const myResource = new MyResource({ someField: 'hello world' }); 
//this produces an error "Argument of type '{ someField: string; }' is not assignable to parameter of type 'Partial<Resource>'"

const anotherResource = MyResource.create({ someField: 'hello world' });
typescript 抽象类 typescript-generics

评论

2赞 jcalz 11/12/2023
这是 TS 缺少的功能,在 ms/TS#5863 中进行了描述,更具体地说在 ms/TS#38038 中进行了描述。因此,没有“直接”的方法可以做到这一点,只有解决方法,例如您已经在使用的静态泛型创建函数。这是否完全解决了这个问题?如果是这样,我会写一个答案来解释;如果没有,我错过了什么?
0赞 heavygl0w 11/13/2023
@jcalz 这是正确的;谢谢!“多态this”的想法正是我想要描述的

答:

1赞 jcalz 11/13/2023 #1

从概念上讲,您希望构造函数接受 类型的参数,使用多态 this 类型。遗憾的是,您当前不能在类的静态端(包括方法)的参数类型中使用多态。在 microsoft/TypeScript#5863 中,更具体地说,在 microsoft/TypeScript#38038 上,有长期未解决的功能请求。除非这些得到实施,否则你不能直接表达你想要的东西。Partial<this>thisconstructor

现在,你只需要解决它。如这些问题中所述,一种常用的解决方法是使用带有 this 参数泛型静态方法。当然,这意味着您需要使用 .我会解释如何做到这一点,除了你已经找到了这个解决方法并在你的示例代码中实现了它。哦,好吧,恐怕目前没有什么比这更好的了。Ctor.create()new Ctor()