Как заставить класс реализовать подпись вызова в Typescript?
Я определил следующий интерфейс в typescript:
interface MyInterface {
() : string;
}
Этот интерфейс просто вводит сигнатуру вызова, которая не принимает никаких параметров и возвращает строку. Как реализовать этот тип в классе? Я пробовал следующее:
class MyType implements MyInterface {
function () : string {
return "Hello World.";
}
}
Компилятор продолжает говорить мне, что
Класс 'MyType' объявляет интерфейс 'MyInterface', но не реализует его: Type 'MyInterface' требует сигнатуры вызова, но Type 'MyType' не имеет одного
Как реализовать подпись вызова?
Ответы
Ответ 1
Классы не могут соответствовать этому интерфейсу. Самое близкое, что вы можете получить, я думаю, это класс, который будет генерировать код, который функционально соответствует интерфейсу (но не в соответствии с компилятором).
class MyType implements MyInterface {
constructor {
return "Hello";
}
}
alert(MyType());
Это сгенерирует рабочий код, но компилятор будет жаловаться, что MyType
не может быть вызван, потому что он имеет подпись new() = 'string'
(даже если вы вызываете его с помощью new
, он вернет объект).
Чтобы создать что-то, что в действительности соответствует интерфейсу без жалобы компилятора, вам нужно будет сделать что-то вроде этого:
var MyType = (() : MyInterface => {
return function() {
return "Hello";
}
})();
alert(MyType());
Ответ 2
Примеры кода в этом ответе предполагают следующее объявление:
var implementation: MyInterface;
Предоставление реализации вызываемого интерфейса
В качестве ответа на принятый ответ, как это было предложено некоторыми из его комментаторов, функция, соответствующая сигнатуре вызова интерфейса, неявно реализует интерфейс. Таким образом, вы можете использовать любую подходящую функцию в качестве реализации.
Например:
implementation = () => "Hello";
Вам не нужно явно указывать, что функция реализует интерфейс. Однако, если вы хотите быть явным, вы можете использовать cast:
implementation = <MyInterface>() => "Hello";
Предоставление возможности повторного использования
Если вы хотите создать многоразовую реализацию интерфейса, как обычно, с интерфейсом Java или С#, просто сохраните функцию где-нибудь доступную для ее потребителей.
Например:
function Greet() {
return "Hello";
}
implementation = Greet;
Предоставление параметризованной реализации
Вы можете захотеть параметризовать реализацию так же, как вы можете параметризовать класс. Вот один из способов сделать это:
function MakeGreeter(greeting: string) {
return () => greeting;
}
implementation = MakeGreeter("Hello");
Если вы хотите, чтобы результат был введен как интерфейс, просто укажите тип возвращаемого значения или измените возвращаемое значение.