gpt4 book ai didi

javascript - Typescript 可以推断由其基方法实例化的扩展类实例的类型吗?

转载 作者:搜寻专家 更新时间:2023-10-30 20:58:37 24 4
gpt4 key购买 nike

考虑以下 Typescript 片段:

class Animal {
constructor(name: string) {
this.name = name;
}
name: string;

haveBaby(name: string): ?? return type ?? {
return new this.constructor(name); // Error
}
}

class Cat extends Animal {}
class Dog extends Animal {}
class Gerbil extends Animal {} // etc.

let sorachi = new Cat("Sorachi"); // a: Cat
let sorachiJr = a.haveBaby("Sorachi Jr."); // I want: sorachiJr: Cat

动物可以有婴儿,婴儿应该是与 parent 相同种类的动物,即应该是与 parent 属于同一类的实例。在这种情况下如何分配类型,以便 Typescript 知道 sorachiJr: Cat

上面的代码片段不起作用。 return new this.constructor(name) 行产生错误 [ts] Cannot use 'new' with an expression whose type lacks a call or construct signature.在 VS 代码中。我能够找到并理解的唯一解决方案是替换 this.constructor(name)(<any>this.constructor)(name)(<any>this).constructor(name) , 但随后为 sorachiJr 推断的类型是any , 而不是 Cat .我尝试转换到 typeof this而不是 any , 但出现错误 [ts] Cannot find name 'this' .

我怎样才能让 Typescript 相信生 child 是一种物种保护行动?

最佳答案

保留调用方法的类的类型很容易,我们只需使用多态的 this 类型。要让 ts 相信 constructor 将是一个接受 string 并返回与当前类类型相同的实例的构造函数,需要类型断言

type AnimalConstructor<T extends Animal> = new (name: string) => T
class Animal {
constructor(name: string) {
this.name = name;
}
name: string;

haveBaby(name: string): this {
return new (this.constructor as AnimalConstructor<this>)(name);
}
}

class Cat extends Animal {}
class Dog extends Animal {}
class Gerbil extends Animal {} // etc.

let sorachi = new Cat("Sorachi"); // a: Cat
let sorachiJr = sorachi.haveBaby("Sorachi Jr.");

注意 Typescript 无法验证派生类构造函数仅需要单个 string 参数这一事实,它可能需要更多或更少的参数。这使得此构造函数类型不安全。

关于javascript - Typescript 可以推断由其基方法实例化的扩展类实例的类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52841793/

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