【问题标题】:Typescript Interface with function. Subtype as parameter not accepted for implementing the interface具有功能的打字稿接口。子类型作为参数不被接受用于实现接口
【发布时间】:2018-09-07 05:13:53
【问题描述】:

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

abstract class FooAbstract{
    constructor(someProp:any){
        this.someProp = someProp;
    }
    someProp:any;
}

class Foo extends FooAbstract{
    constructor(prop:any){
        super(prop);
    }
    someRandomFunction(){
        console.log("Something")
    }
}

我有一个界面,其功能如下图所示

interface ExampleInterface{
    someFunction: (foo:FooAbstract)=>any;
}

现在我想实现接口,但想在接口实现中传递子类型作为函数someFunction的参数,如下所示

class Example implements ExampleInterface{
    someFunction = (foo:Foo)=>{
        console.log("Hello World");
    }
}

Typescript 警告 someFunction 的实现不正确,类型 Foo 和 FooAbstract 不兼容。我想了解为什么我不能通过要求 FooAbstract

的子类型作为参数来实现函数 someFunction

【问题讨论】:

  • 因为不是所有的FooAbstracts 都是Foos - 如果someFunction 依赖于someRandomFunction 那么它就不能接受FooAbstract 的一些实现者。你不能缩小参数类型(同样你不能扩大返回类型)。

标签: typescript abstraction


【解决方案1】:

实际上这是有道理的,因为这样做并不安全。考虑以下场景:

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

如果编译器允许您的问题中的场景,上述代码将编译但在运行时失败,因为someRandomFunctionBoo 上不存在。

您可以将接口设为通用,这样您就可以指定要使用的派生FooAbsrtact 的类型:

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

【讨论】:

  • 是的,这是有道理的。只有类被抽象,而函数实现仍然存在。感谢您的回复
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-04
  • 2021-10-11
  • 2017-09-16
  • 1970-01-01
  • 2019-03-26
  • 2017-08-31
相关资源
最近更新 更多