如何让一个类在 Typescript 中实现调用签名?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12769636/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make a class implement a call signature in Typescript?
提问by Valentin
I have defined the following interface in typescript:
我在打字稿中定义了以下接口:
interface MyInterface {
() : string;
}
This interface simply introduces a call signature that takes no parameters and returns a string. How do I implement this type in a class? I have tried the following:
这个接口简单地引入了一个不带参数并返回一个字符串的调用签名。如何在类中实现这种类型?我尝试了以下方法:
class MyType implements MyInterface {
function () : string {
return "Hello World.";
}
}
The compiler keeps telling me that
编译器一直告诉我
Class 'MyType' declares interface 'MyInterface' but does not implement it: Type 'MyInterface' requires a call signature, but Type 'MyType' lacks one
类“MyType”声明接口“MyInterface”但未实现它:“MyInterface”类型需要调用签名,但“MyType”类型缺少调用签名
How can I implement the call signature?
如何实现调用签名?
采纳答案by Peter Olson
Classes can't match that interface. The closest you can get, I think is this class, which will generate code that functionally matches the interface (but not according to the compiler).
类无法匹配该接口。你能得到的最接近的是这个类,它将生成在功能上与接口匹配的代码(但不是根据编译器)。
class MyType implements MyInterface {
constructor {
return "Hello";
}
}
alert(MyType());
This will generate working code, but the compiler will complain that MyTypeis not callable because it has the signature new() = 'string'(even though if you call it with new, it will return an object).
这将生成工作代码,但编译器会抱怨它MyType不可调用,因为它有签名new() = 'string'(即使你用 调用它new,它也会返回一个对象)。
To create something that actally matches the interface without the compiler complaining, you'll have to do something like this:
要创建与接口实际匹配的内容而编译器不会抱怨,您必须执行以下操作:
var MyType = (() : MyInterface => {
return function() {
return "Hello";
}
})();
alert(MyType());
回答by Sam
The code examples in this answer assume the following declaration:
此答案中的代码示例假定以下声明:
var implementation: MyInterface;
Providing an implementation of a callable interface
提供可调用接口的实现
As a follow-up to the accepted answer, as suggested by some of its commentors, a function that matches the interface's call signature implicitly implements the interface. So you can use any matching function as an implementation.
作为已接受答案的后续行动,正如其一些评论者所建议的那样,与接口的调用签名匹配的函数隐式地实现了该接口。因此,您可以使用任何匹配函数作为实现。
For example:
例如:
implementation = () => "Hello";
You don't need to explicitly specify that the function implements the interface. However, if you want to be explicit, you can use a cast:
您不需要显式指定函数实现接口。但是,如果您想明确表示,可以使用强制转换:
implementation = <MyInterface>() => "Hello";
Providing a reusable implementation
提供可重用的实现
If you want to produce a reusable implementation of the interface like you normally would with a Java or C# interface, just store the function somewhere accessible to its consumers.
如果您想像通常使用 Java 或 C# 接口一样生成接口的可重用实现,只需将该函数存储在其使用者可访问的位置即可。
For example:
例如:
function Greet() {
return "Hello";
}
implementation = Greet;
Providing a parameterised implementation
提供参数化的实现
You may want to be able to parameterise the implementation in the same way that you might parameterise a class. Here's one way to do this:
您可能希望能够以与参数化类相同的方式来参数化实现。这是执行此操作的一种方法:
function MakeGreeter(greeting: string) {
return () => greeting;
}
implementation = MakeGreeter("Hello");
If you want the result to be typed as the interface, just explicitly set the return type or cast the value being returned.
如果您希望将结果输入为接口,只需显式设置返回类型或强制转换返回的值。
回答by teq
In case if callable interface should have other methods you can do it like this:
如果可调用接口应该有其他方法,您可以这样做:
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!'
Downside: greeter instanceof ConsoleGreeteris false
缺点:greeter instanceof ConsoleGreeter是false

