gpt4 book ai didi

TypeScript:定义了解子类属性的父类构造函数

转载 作者:行者123 更新时间:2023-12-03 08:16:18 24 4
gpt4 key购买 nike

abstract class Parent {
public foo: string;

constructor(v: Partial<Parent>) {
Object.assign(this, v);
}
}

class ChildA extends Parent {
bar: string;
}

class ChildB extends Parent {
baz: string
}

在此设置中,

const a = new ChildA({ foo: 'foo', bar: 'bar'});

出现以下错误。

TS2345: Argument of type '{ foo: string; bar: string }' is not assignable to parameter of type 'Partial<Parent>'.
Object literal may only specify known properties, and 'bar' does not exist in type 'Partial<Parent>'.

constructor<T extends Parent>(v: Partial<T>)也不行。 (TS1092:类型参数不能出现在构造函数声明中。)

我可以以类型安全的方式定义类 Parent、ChildA 和 ChildB 的构造函数吗?

最佳答案

您想使用the polymorphic this type内部构造函数参数。

不幸的是,这是明确不支持的;请参阅microsoft/TypeScript#5449 ,特别是this comment ,以及相关功能请求 microsoft/TypeScript#5863 。有一个相对较新的功能请求允许 this在构造函数参数中 microsoft/TypeScript#40451 。那么,现在没有简单的方法告诉编译器您希望构造函数参数依赖于“当前”类构造函数的类型(从而由子类继承)。

如果您想要这种行为,您将无法从 TypeScript 中免费获得它;你必须解决这个问题。


多态-this是一种“隐式”F-bounded polymorphism ,这意味着您可以想到 this就像 generic类型参数为 constrained对自己。由于我们无法拥有构造函数参数的隐式版本,因此也许我们可以通过向类添加自界型参数来显式地做到这一点:

abstract class Parent<T extends Parent<T>> {
public foo: string = "";

constructor(v: Partial<T>) {
Object.assign(this, v);
}
}

这有效;请注意 Parent<T> 中的方式,类型参数T被限制为 Parent<T>本身。现在我们可以使用T代替this类型。当我们声明子类时,我们需要明确这一点:

class ChildA extends Parent<ChildA> {
bar: string = "";
}

class ChildB extends Parent<ChildB> {
baz: string = ""
}

现在您的子类的行为符合预期:

new ChildA({ foo: 'foo', bar: 'bar' }).bar;

您提到您可能想给予 T一个default这样你就可以只提及 Parent在代码的其他部分。对于这种默认设置,您有多种选择,具体取决于您想要的迂腐与方便程度。最方便的是any ,下一个最迂腐的东西是 Parent<any> ,然后是 Parent<Parent<any>> (根据需要重复),然后是极端版本:

type ParentItself = Parent<ParentItself>;
abstract class Parent<T extends Parent<T> = ParentItself> { /* ... */ }

也许您甚至想要never作为默认值,这可能会突出显示 Parent 的任何意外使用。在只有具体子类才有意义的地方。您需要根据您的用例检查这些内容,看看哪些(如果有)适合。

Playground link to code

关于TypeScript:定义了解子类属性的父类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69263012/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com