1

在学习 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)

该代码来自我发现的一篇博客文章,我看到(可能是错误的)作者将派生类中“SomeMethod”的签名更改为不带参数的东西。然后他实例化了两个对象,一个是“Derived1”类型,一个是“Derived2”类型。在第一种情况下,他曾经var自动将“one”设为 type Derived1。然而,在第二种情况下,他通过var two:Base = ...- 声明它,因此他使用“指向基址的指针”来访问它。

由于基类有一个“SomeMethod”原型,事实上,它接受一个参数,调用two.SomeMethod(34)实际上是从编译传递的,但在运行时,调用 Derived2 版本:

Derived1
one  called with param:2
Derived2
two  called with param:4

这不是错误吗?打字稿编译器不应该抓住这种情况吗?

4

1 回答 1

1

不,它不应该是编译器错误。只要类型兼容,您应该可以自由声明您认为适合您的类的任何签名。例如 void (如您的示例)或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));
    }
}
于 2013-09-05T11:35:38.343 回答