带功能的打字稿接口.实现接口时不接受子类型作为参数 [英] Typescript Interface with function. Subtype as parameter not accepted for implementing the interface
问题描述
我有一个类扩展了另一个类,如下所示
I have a class which extends another class as shown below
abstract class FooAbstract{
constructor(someProp:any){
this.someProp = someProp;
}
someProp:any;
}
class Foo extends FooAbstract{
constructor(prop:any){
super(prop);
}
someRandomFunction(){
console.log("Something")
}
}
我有一个功能如下图所示的界面
I have an interface which has a function as shown below
interface ExampleInterface{
someFunction: (foo:FooAbstract)=>any;
}
现在我想实现接口但想在接口实现中将子类型作为函数someFunction的参数传递,如下图
Now I want to implement the interface but want to pass subtype as parameter of the function someFunction in the interface implementation as shown below
class Example implements ExampleInterface{
someFunction = (foo:Foo)=>{
console.log("Hello World");
}
}
Typescript 警告 someFunction 的实现不正确,并且类型 Foo 和 FooAbstract 不兼容.我想了解为什么我不能通过要求 FooAbstract
Typescript is warning that the implementation of someFunction is incorrect and the type Foo and FooAbstract are incompatible. I want to understand why can't I implement the function someFunction by requiring as a parameter a subtype of FooAbstract
推荐答案
实际上这是有道理的,因为这样做并不安全.考虑以下场景:
Actually this makes sense because it is not safe to do this. Consider the following scenario:
class Example implements ExampleInterface{
someFunction = (foo:Foo)=>{
console.log("Hello World");
foo.someRandomFunction() // we can call this since foo is of type Foo
}
}
class Boo extends FooAbstract{
constructor(prop:any){
super(prop);
}
// no someRandomFunction method
}
var ex: ExampleInterface = new Example();
ex.someFunction(new Boo({})) // ok, Boo is derived from FooAbstract
如果编译器允许您的问题中的场景,则上述代码将编译但在运行时失败,因为 Boo
上不存在 someRandomFunction
.
If the compiler would allow the scenario in your question, the above code would compile but fail at runtime because someRandomFunction
does not exist on Boo
.
您可以使接口通用,以便指定您将使用的派生 FooAbsrtact
类型:
You can make the interface generic so you can specify what type of derived FooAbsrtact
you will use:
interface ExampleInterface< T extends FooAbstract >{
someFunction: (foo:T)=>any;
}
// now ok
class Example implements ExampleInterface<Foo>{
someFunction = (foo:Foo)=>{
console.log("Hello World");
foo.someRandomFunction()
}
}
class Boo extends FooAbstract{
constructor(prop:any){
super(prop);
}
// no someRandomFunction method
}
var ex: ExampleInterface<Foo> = new Example();
ex.someFunction(new Boo({})) // compile error as it should be
这篇关于带功能的打字稿接口.实现接口时不接受子类型作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!