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

nx7onnlm  于 2023-11-20  发布在  TypeScript
关注(0)|答案(1)|浏览(201)

我有一个抽象类,它将接受传入构造函数的任何数据并将其赋值给示例。目标是您可以使用其数据的子集初始化示例。
我遇到的问题是,一旦抽象类被扩展,子类构造函数就需要一个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' });

字符串

s4n0splo

s4n0splo1#

从概念上讲,您希望构造函数使用多态this类型接受Partial<this>类型的参数。不幸的是,您目前无法在类的静态端的参数类型中使用多态this,其中包括constructor方法。在microsoft/TypeScript#5863上,更具体地说,在microsoft/TypeScript#38038上,有长期开放的功能请求。直到和除非这些得到实现,否则你不能直接表达你想要的。
现在,你只需要解决它。一个流行的解决方法,就像那些问题中提到的,是使用带有this参数的generic静态方法。当然,这意味着你需要使用Ctor.create()而不是new Ctor()。我会解释如何做到这一点,除了你已经找到了这个解决方法并在示例代码中实现了它。哦,好吧,恐怕目前没有比这更好的了。

相关问题