我想扩展一个类,并将其动态类型折叠为特定类型(从T
到Person
)。
我为这个例子创建了虚拟类:
class Person {
constructor(public name: string){}
}
class Base<T> {
reference?: T
name: string
constructor(name: string) {
// Assign properties from T to this
this.name = name
}
static fromObject<T extends { name: string }>(object: T){
const base = new Base(object.name)
base.reference = object
return base
}
}
class Master<T> extends Base<T> {
static fromBase<T>(base: Base<T>){
const master = new Master(base.name)
master.reference = base.reference
return master
}
static fromObject<T extends { name: string }>(object: T){
return Master.fromBase(Base.fromObject(object))
}
}
class PersonMaster extends Master<Person> {
constructor(person: Person){
super(person.name)
this.reference = person
}
static fromBase(base: Base<Person>){
return new PersonMaster(base)
}
}
编译器返回此错误:
类静态端typeof PersonMaster
错误地扩展了基类静态端typeof Master
。属性类型fromBase
不兼容。类型(base: Base<Person>) => PersonMaster
不能分配<T>(base: Base<T>) => Master<{}>
类型。参数类型base
和base
不兼容。类型Base<T>
无法分配给Base<Person>
。类型T
不能分配Person
类型。
答案 0 :(得分:1)
fromBase
中Master
的声明是通用的:
static fromBase<T>(base: Base<T>)
这是通用量化:它表示fromBase
适用于所有T
。因此,当您尝试将Base<Person>
中的参数专门化为PersonMaster
时,类型检查器会正确地抱怨fromBase
的此实现不适用于所有T
,仅适用于Person
。重写方法的类型参数必须与声明的方法的类型参数匹配。
换句话说,T
中声明的fromBase
与封闭范围中的T
完全不同class Master<T> extends Base<T> {
static fromBase<U>(base: Base<U>) { /* ... */ }
}
。它恰好影响了这个名字。如果两个类型参数具有不同的名称,则可能更容易理解:
T
在这种情况下,我怀疑您打算使用Master
中的(严格)T
,而不是新鲜的(更高级别 )interface MasterFactory<T> {
fromBase(base: Base<T>): Master<T>
}
class PersonMasterFactory implements MasterFactory<Person> {
fromBase(base: Base<Person>): Master<Person> { /* ... */ }
}
let personMasterFactory = new PersonMasterFactory();
。遗憾的是,正如您在评论中指出的那样,您无法使用静态方法来执行此操作,因为TypeScript不支持它。 (我无法找到任何关于语言设计师为什么做出这个决定的文档。我个人想不出任何好的理由,虽然我确定有一个。)所以你必须把你的方法转移到某个其他对象的实例方法:
PersonMaster.fromBase
通过此设计,可以转到personMasterFactory.fromBase
的来电将转到var Season = [];
。
首先覆盖静态方法是一件非常奇怪的事情。方法覆盖是基于接收器的类型动态地调度调用,但是(概念上,至少)静态方法没有接收器。名称中的线索:动态调度静态方法没有意义!