在学习Typescript时,我在网络上的某个地方偶然发现了这个例子。我很惊讶地看到这实际上是在编译:
class Base {
constructor (public name) { }
SomeMethod(param:number) {
console.log(this.name + " " + " called with param:" + param);
}
}
class Derived1 extends Base {
constructor(name) { super(name); }
SomeMethod() {
console.log("Derived1");
super.SomeMethod(2);
}
}
class Derived2 extends Base {
constructor(name) { super(name); }
SomeMethod() {
console.log("Derived2");
super.SomeMethod(4);
}
}
var one = new Derived1("one")
var two:Base = new Derived2("two")
one.SomeMethod()
two.SomeMethod(34)
代码来自我发现的博客文章,我看到(可能是错误的)作者改变了#34; SomeMethod"在派生类中,对于没有参数的东西。然后他实例化了两个对象,一个类型" Derived1"和#34; Derived2"之一。在第一种情况下,他使用var
自动制作"一个"属于Derived1
类型。然而,在第二种情况下,他通过var two:Base = ...
声明了它 - 所以他使用了一个"指向基地"访问它。
由于基类有一个" SomeMethod"事实上,实际上采用参数的原型,调用two.SomeMethod(34)
实际上是从编译传递的,但在运行时调用Derived2版本:
Derived1
one called with param:2
Derived2
two called with param:4
这不是错误吗?打字稿编译器不应该抓住这种情况吗?
答案 0 :(得分:1)
没有。它不应该是编译器错误。只要类型兼容,您就可以自由声明任何适合您的类的签名。例如无效(如您的示例中)或any
,如下例所示:
class Base {
constructor (public name) { }
SomeMethod(param:number) {
console.log(this.name + " " + " called with param:" + param);
}
}
class Derived1 extends Base {
constructor(name) { super(name); }
SomeMethod(param:any) { // is compatible
console.log("Derived1");
super.SomeMethod(parseInt(param,10));
}
}
的工作原理。但是string
会产生编译错误:
class Base {
constructor (public name) { }
SomeMethod(param:number) {
console.log(this.name + " " + " called with param:" + param);
}
}
class Derived1 extends Base {
constructor(name) { super(name); }
SomeMethod(param:string) { // not compatible, compiler error
console.log("Derived1");
super.SomeMethod(parseInt(param,10));
}
}