Определение типа обратного вызова TypeScript

У меня есть следующий класс в TypeScript:

class CallbackTest
{
    public myCallback;

    public doWork(): void
    {
        //doing some work...
        this.myCallback(); //calling callback
    }
}

Я использую класс следующим образом:

var test = new CallbackTest();
test.myCallback = () => alert("done");
test.doWork();

Код работает, поэтому он отображает окно сообщений, как ожидалось.

Мой вопрос: есть ли какой-либо тип, который я могу предоставить для своего поля класса myCallback? Сейчас публичное поле myCallback имеет тип any, как показано выше. Как определить сигнатуру метода обратного вызова? Или я могу просто задать тип типа обратного вызова? Или я могу сделать это? Должен ли я использовать any (неявный/явный)?

Я пробовал что-то вроде этого, но это не сработало (ошибка времени компиляции):

public myCallback: ();
// or:
public myCallback: function;

Я не мог найти никаких объяснений этому онлайн, поэтому надеюсь, что вы сможете мне помочь.

Ответ 1

Я только что нашел что-то в спецификации языка TypeScript, это довольно просто. Я был довольно близок.

синтаксис следующий:

public myCallback: (name: type) => returntype;

В моем примере это будет

class CallbackTest
{
    public myCallback: () => void;

    public doWork(): void
    {
        //doing some work...
        this.myCallback(); //calling callback
    }
}

Ответ 2

Чтобы сделать еще один шаг, вы можете объявить указатель типа на подпись функции, например:

interface myCallbackType { (myArgument: string): void }

и используйте его следующим образом:

public myCallback : myCallbackType;

Ответ 3

Вы можете объявить новый тип:

declare type MyHandler = (myArgument: string) => void;

var handler: MyHandler;

Update.

Ключевое слово declare не требуется. Он должен использоваться в файлах .d.ts или в подобных случаях.

Ответ 4

Вот пример - не принимать никаких параметров и ничего не возвращать.

class CallbackTest
{
    public myCallback: {(): void;};

    public doWork(): void
    {
        //doing some work...
        this.myCallback(); //calling callback
    }
}

var test = new CallbackTest();
test.myCallback = () => alert("done");
test.doWork();

Если вы хотите принять параметр, вы также можете добавить это:

public myCallback: {(msg: string): void;};

И если вы хотите вернуть значение, вы можете добавить это также:

public myCallback: {(msg: string): number;};

Ответ 5

Если вы хотите использовать общую функцию, вы можете использовать следующее. Хотя, похоже, он нигде не документирован.

class CallbackTest {
  myCallback: Function;
}   

Ответ 6

Я столкнулся с той же ошибкой при попытке добавить обратный вызов к прослушивателю событий. Как ни странно, установка типа обратного вызова EventListener решила его. Он выглядит более элегантным, чем определение целой функции как типа, но я не уверен, что это правильный способ сделать это.

class driving {
    // the answer from this post - this works
    // private callback: () => void; 

    // this also works!
    private callback:EventListener;

    constructor(){
        this.callback = () => this.startJump();
        window.addEventListener("keydown", this.callback);
    }

    startJump():void {
        console.log("jump!");
        window.removeEventListener("keydown", this.callback);
    }
}

Ответ 7

Вы можете использовать следующее:

  1. Введите Alias (используя ключевое слово type, псевдоним функционального литерала)
  2. интерфейсФункциональный литерал

Вот пример того, как их использовать:

type myCallbackType = (arg1: string, arg2: boolean) => number;

interface myCallbackInterface { (arg1: string, arg2: boolean): number };

class CallbackTest
{
    // ...

    public myCallback2: myCallbackType;
    public myCallback3: myCallbackInterface;
    public myCallback1: (arg1: string, arg2: boolean) => number;

    // ...

}