如何使类在Typescript中实现调用签名?

时间:2012-10-07 14:22:10

标签: typescript

我在typescript中定义了以下接口:

interface MyInterface {
    () : string;
}

此接口简单地引入了一个不带参数的调用签名并返回一个字符串。如何在类中实现此类型?我尝试过以下方法:

class MyType implements MyInterface {
    function () : string {
        return "Hello World.";
    }
}

编译器一直告诉我

  

类'MyType'声明接口'MyInterface'但未实现它:Type'MyInterface'需要调用签名,但Type'MyType'缺少一个

如何实施呼叫签名?

3 个答案:

答案 0 :(得分:12)

类与该接口不匹配。你能得到的最接近的,我认为是这个类,它将生成与接口功能匹配的代码(但不是根据编译器)。

class MyType implements MyInterface {
  constructor {
    return "Hello";
  }
}
alert(MyType());

这将生成工作代码,但编译器会抱怨MyType不可调用,因为它具有签名new() = 'string'(即使你用new调用它,它也会返回一个东西)。

要在没有编译器抱怨的情况下创建与界面完全匹配的内容,您必须执行以下操作:

var MyType = (() : MyInterface => {
  return function() { 
    return "Hello"; 
  }
})();
alert(MyType());

答案 1 :(得分:6)

本回答中的代码示例假设以下声明:

var implementation: MyInterface;

提供可调用接口的实现

作为the accepted answer的后续行动,正如其评论员所建议的那样,与接口的调用签名匹配的函数隐式实现了接口。因此,您可以使用任何匹配函数作为实现。

例如:

implementation = () => "Hello";

您无需明确指定该函数实现该接口。但是,如果您想要明确,可以使用强制转换:

implementation = <MyInterface>() => "Hello";

提供可重用的实现

如果您想像通常使用Java或C#接口那样生成可重用的接口实现,只需将该功能存储在其消费者可访问的位置。

例如:

function Greet() {
    return "Hello";
}

implementation = Greet;

提供参数化实现

您可能希望能够以与参数化类相同的方式参数化实现。这是一种方法:

function MakeGreeter(greeting: string) {
    return () => greeting;
}

implementation = MakeGreeter("Hello");

如果要将结果键入为接口,只需显式设置返回类型或转换返回的值。

答案 2 :(得分:2)

如果可调用接口应该有其他方法,你可以这样做:

interface Greeter {
    (): void;
    setName(name: string): void;
}

class ConsoleGreeter {

    private constructor( // constructable via `create()`
        private name = 'world'
    ) {}

    public call(): void {
        console.log(`Hello ${this.name}!`);
    }

    public setName(name: string) {
        this.name = name;
    }

    public static create(): Greeter {
        const instance = new ConsoleGreeter();
        return Object.assign(
            () => instance.call(),
            {
                setName: (name: string) => instance.setName(name)
                // ... forward other methods
            }
        );
    }
}

const greeter = ConsoleGreeter.create();
greeter(); // prints 'Hello world!'
greeter.setName('Dolly');
greeter(); // prints 'Hello Dolly!'

下行:greeter instanceof ConsoleGreeterfalse