带功能的打字稿接口.实现接口时不接受子类型作为参数 [英] Typescript Interface with function. Subtype as parameter not accepted for implementing the interface

查看:30
本文介绍了带功能的打字稿接口.实现接口时不接受子类型作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类扩展了另一个类,如下所示

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆