42

我在打字稿中定义了以下接口:

interface MyInterface {
    () : string;
}

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

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

编译器一直告诉我

“MyType”类声明了“MyInterface”接口,但没有实现它:“MyInterface”类型需要调用签名,但“MyType”类型缺少调用签名

如何实现调用签名?

4

3 回答 3

16

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

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

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

要创建与接口完全匹配而编译器不会抱怨的东西,您必须执行以下操作:

var MyType = (() : MyInterface => {
  return function() { 
    return "Hello"; 
  }
})();
alert(MyType());
于 2012-10-07T15:32:22.540 回答
10

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

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

于 2018-01-25T08:08:33.147 回答
7

此答案中的代码示例假定以下声明:

var implementation: MyInterface;

提供可调用接口的实现

作为已接受答案的后续行动,正如其一些评论者所建议的那样,与接口的调用签名匹配的函数隐式地实现了接口。所以你可以使用任何匹配的函数作为实现。

例如:

implementation = () => "Hello";

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

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

提供可重用的实现

如果您想像通常使用 Java 或 C# 接口一样生成接口的可重用实现,只需将函数存储在其使用者可访问的位置即可。

例如:

function Greet() {
    return "Hello";
}

implementation = Greet;

提供参数化实现

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

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

implementation = MakeGreeter("Hello");

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

于 2013-12-23T01:45:18.517 回答