定义TypeScript回调类型

nik*_*eee 146 types callback typescript

我在TypeScript中有以下类:

class CallbackTest
{
    public myCallback;

    public doWork(): void
    {
        //doing some work...
        this.myCallback(); //calling callback
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在使用这样的类:

var test = new CallbackTest();
test.myCallback = () => alert("done");
test.doWork();
Run Code Online (Sandbox Code Playgroud)

代码有效,因此它会按预期显示消息框.

我的问题是:我可以为我的课程领域提供任何类型的课程myCallback吗?现在,公共字段myCallback的类型any如上所示.如何定义回调的方法签名?或者我可以将类型设置为某种回调类型?或者我可以做些什么吗?我必须使用any(隐式/显式)吗?

我试过这样的东西,但它不起作用(编译时错误):

public myCallback: ();
// or:
public myCallback: function;
Run Code Online (Sandbox Code Playgroud)

我在网上找不到任何解释,所以我希望你能帮助我.

nik*_*eee 187

我刚刚在TypeScript语言规范中找到了一些东西,它相当容易.我非常接近.

语法如下:

public myCallback: (name: type) => returntype;
Run Code Online (Sandbox Code Playgroud)

在我的例子中,它将是

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

    public doWork(): void
    {
        //doing some work...
        this.myCallback(); //calling callback
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我不明白为什么需要参数名来定义回调签名... (7认同)
  • 我想可能是[C#团队的文化遗产](/sf/answers/859092811/),我想我毕竟还是喜欢的... (3认同)

小智 132

为了更进一步,您可以声明一个指向函数签名的类型指针,如:

interface myCallbackType { (myArgument: string): void }
Run Code Online (Sandbox Code Playgroud)

并像这样使用它:

public myCallback : myCallbackType;
Run Code Online (Sandbox Code Playgroud)

  • 这是(IMO)比接受的答案更好的解决方案,因为它允许您定义一个类型,然后传递该类型的参数(回调),然后您可以以任何方式使用它,包括调用它.接受的答案使用成员变量,您必须将成员变量设置为您的函数,然后调用方法 - 丑陋且容易出错,因为首先设置变量是调用方法的合同的一部分. (9认同)
  • 请注意,TSLint 会抱怨 _“TSLint:接口只有一个调用签名 - 请改用 `type MyHandler = (myArgument: string) => void`。(可调用类型)”_; 请参阅[TSV的答案](/sf/ask/919614531/#33173494) (3认同)

TSV*_*TSV 52

您可以声明一个新类型:

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

var handler: MyHandler;
Run Code Online (Sandbox Code Playgroud)

更新.

declare关键字是没有必要的.它应该在.d.ts文件或类似情况下使用.


Fen*_*ton 29

这是一个例子 - 不接受任何参数并且不返回任何参数.

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();
Run Code Online (Sandbox Code Playgroud)

如果您想接受参数,也可以添加它:

public myCallback: {(msg: string): void;};
Run Code Online (Sandbox Code Playgroud)

如果你想返回一个值,你也可以添加它:

public myCallback: {(msg: string): number;};
Run Code Online (Sandbox Code Playgroud)

  • @nikeee:问题是你的答案有什么不同?史蒂夫在你面前发了他的答案. (6认同)

Ash*_*lue 12

如果您想要通用功能,可以使用以下功能.虽然它似乎没有在任何地方记录.

class CallbackTest {
  myCallback: Function;
}   
Run Code Online (Sandbox Code Playgroud)


Wil*_*een 6

您可以使用以下内容:

  1. 类型别名(使用type关键字,为函数字面量取别名)
  2. 界面
  3. 函数字面量

以下是如何使用它们的示例:

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;

    // ...

}
Run Code Online (Sandbox Code Playgroud)


Dan*_*iel 6

我有点晚了,但是,因为前段时间在 TypeScript 中,您可以使用以下命令定义回调类型

type MyCallback = (KeyboardEvent) => void;
Run Code Online (Sandbox Code Playgroud)

使用示例:

this.addEvent(document, "keydown", (e) => {
    if (e.keyCode === 1) {
      e.preventDefault();
    }
});

addEvent(element, eventName, callback: MyCallback) {
    element.addEventListener(eventName, callback, false);
}
Run Code Online (Sandbox Code Playgroud)