我在TypeScript中使用extends
约束,如下所示:
class Animal {}
class Lion extends Animal {}
class Bear extends Animal { }
class ZooKeeper<T extends Animal> {
constructor(p: T = new Animal()) {
}
}
new ZooKeeper(new Animal());
但p: T = new Animal()
包含错误:
Type&#39; Animal&#39;不能分配给&#39; T&#39;。
构造函数Animal():Animal
为什么,我该怎么做才能使用Animal
代替Animal
子类型?
答案 0 :(得分:2)
将你的动物投射到T上它会起作用。
class ZooKeeper<T extends Animal> {
constructor(p: T = <T>new Animal()) {
}
}
根据您自己的评论(对于未来的读者),您也可以这样做:
class ZooKeeper<T extends Animal> {
constructor(p: T = new Animal() as T) {
}
}
答案 1 :(得分:1)
你可以从构造函数参数声明中保留赋值,似乎正在为我编译。如果你想留下它,你甚至可以让参数成为可选参数。
更新:正如series0ne所指出的,此解决方案未提供Animal
的默认实例,其中未提供一个!{/ p>
class ZooKeeper<T extends Animal> {
constructor(p?: T) {
}
}
var zk = new ZooKeeper<Lion>(new Lion());
var zk2 = new ZooKeeper(new Animal());
var zk3 = new ZooKeeper();
将输入ZooKeeper
类,您可以访问T
的子类特定属性。
答案 2 :(得分:0)
实际上,要完成您想做的事情并不容易。 Animal
无法分配给T
,因为它们是不同的类型。
考虑示例:
class Lion extends Animal {
roar() { … }
}
new ZooKeeper<Lion>().animal.roar();
您可以运行它here来查看它在运行时引发异常,因为即使我们将Lion
作为T
类型传递,我们也会显式创建Animal
对象,没有T
类型的成员。而且我们无法在构造函数中编写new T()
,因为在运行时不存在有关类型的所有信息。
值得一提的是,仅在明确需要时才使用结构<Type>object
或object as Type
,因为它不是强制转换,而是类型断言(它告诉编译器'处理' object
就像Type
一样,即使它不是'?),因此当用作“广播”时,可能会导致难以发现错误。