Typescript 可以推断由其基础方法实例化的扩展实例 class 的类型吗?
Can Typescript infer the type of an instance of an extension class instantiated by a method of its base?
考虑以下 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 相同的 class 的实例。在这种情况下如何分配类型,以便 Typescript 知道 sorachiJr: Cat
?
上面的代码片段不起作用。行 return new this.constructor(name)
在 VS Code 中产生错误 [ts] Cannot use 'new' with an expression whose type lacks a call or construct signature.
。我能够找到并理解的唯一解决方案是将 this.constructor(name)
替换为 (<any>this.constructor)(name)
或 (<any>this).constructor(name)
,但是 sorachiJr
的推断类型也是 any
,而不是 Cat
。我尝试转换为 typeof this
而不是 any
,但出现错误 [ts] Cannot find name 'this'
.
如何让 Typescript 相信生孩子是一项 species-preserving 操作?
保存 class 调用方法的类型很容易,我们只需使用多态 this
类型。要说服 ts constructor
将是一个构造函数,它采用 string
和 returns 与当前 class 类型相同的实例需要类型断言
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 无法验证派生的 class 构造函数只需要一个 string
参数的事实,它可能需要更多或更少的参数.这使得此构造函数类型不安全。
考虑以下 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 相同的 class 的实例。在这种情况下如何分配类型,以便 Typescript 知道 sorachiJr: Cat
?
上面的代码片段不起作用。行 return new this.constructor(name)
在 VS Code 中产生错误 [ts] Cannot use 'new' with an expression whose type lacks a call or construct signature.
。我能够找到并理解的唯一解决方案是将 this.constructor(name)
替换为 (<any>this.constructor)(name)
或 (<any>this).constructor(name)
,但是 sorachiJr
的推断类型也是 any
,而不是 Cat
。我尝试转换为 typeof this
而不是 any
,但出现错误 [ts] Cannot find name 'this'
.
如何让 Typescript 相信生孩子是一项 species-preserving 操作?
保存 class 调用方法的类型很容易,我们只需使用多态 this
类型。要说服 ts constructor
将是一个构造函数,它采用 string
和 returns 与当前 class 类型相同的实例需要类型断言
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 无法验证派生的 class 构造函数只需要一个 string
参数的事实,它可能需要更多或更少的参数.这使得此构造函数类型不安全。