Types 定义类型脚本回调类型

Types 定义类型脚本回调类型,types,callback,typescript,Types,Callback,Typescript,我在TypeScript中有以下课程: class CallbackTest { public myCallback; public doWork(): void { //doing some work... this.myCallback(); //calling callback } } 我是这样使用这个类的: var test = new CallbackTest(); test.myCallback = () =>

我在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();
public myCallback : myCallbackType;
代码正常工作,因此它按预期显示messagebox

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

我尝试了类似的方法,但没有成功(编译时错误):


我在网上找不到对此的任何解释,因此我希望您能帮助我。

这里有一个示例-不接受任何参数,不返回任何内容

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;};

我刚刚在TypeScript语言规范中找到了一些东西,它相当简单。我很接近

语法如下所示:

public myCallback: (name: type) => returntype;
在我的例子中,它是

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

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

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

interface myCallbackType { (myArgument: string): void }
然后像这样使用它:

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

您可以声明一个新类型:

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

var handler: MyHandler;
更新。
declare
关键字不是必需的。它应该在.d.ts文件或类似情况下使用。

如果您想要一个通用函数,可以使用以下命令。尽管它似乎没有任何地方被记录下来

class CallbackTest {
  myCallback: Function;
}   

我在尝试将回调添加到事件侦听器时遇到了相同的错误。奇怪的是,将回调类型设置为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);
    }
}

您可以使用以下选项:

public myCallback: (name: type) => returntype;
  • 类型别名(使用
    Type
    关键字,为函数文本添加别名)
  • 接口
  • 函数文字

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

    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;
    
        // ...
    
    }
    

    我有点晚了,但是,因为不久前在TypeScript中,您可以使用

    type MyCallback = (KeyboardEvent) => void;
    
    使用示例:

    this.addEvent(document, "keydown", (e) => {
        if (e.keyCode === 1) {
          e.preventDefault();
        }
    });
    
    addEvent(element, eventName, callback: MyCallback) {
        element.addEventListener(eventName, callback, false);
    }
    

    下面是我如何定义包含回调的接口的一个简单示例

    //包含回调的接口
    接口惊奇输入{
    名称:string
    回调:(字符串)=>void//定义回调
    }
    //正在调用的方法
    公众言论令人惊讶(数据:惊奇输入){
    设置超时(()=>{
    data.callback(data.name+“这太棒了!”);
    }, 1000)
    }
    //基于接口创建一个参数
    let输入:amazingput={
    名字:“乔·索普”
    回调:(消息)=>{
    console.log('惊人的消息是:'+消息);
    }
    }
    //调用方法,传入参数
    说话人(输入);
    
    这是一个用于角度组件和服务的可选回调函数示例


    它们在功能上是相同的——它们定义了相同的东西,并对函数签名进行类型检查。你可以用你喜欢的任何一种。规格上说它们是完全相同的
    @nikeee:问题是你的答案有什么不同?史蒂夫把他的答案贴在你的答案之前。@jgauffin的确,结果是一样的。在我看来,我发布的解决方案在谈到回调时更为自然,因为Steve的版本允许完整的接口定义。这取决于您的偏好。@Fenton您能提供一个指向该文档的链接吗?这(依我看)是一个比公认答案好得多的解决方案,因为它允许您定义一个类型,然后,比方说,传递一个该类型的参数(回调),然后您可以以任何方式使用它,包括调用它。接受的答案使用一个成员变量,您必须将该成员变量设置为您的函数,然后调用一个方法-丑陋且容易出错,因为首先设置该变量是调用该方法的契约的一部分。它还允许您轻松地将回调设置为可为null,例如,
    let callback:myCallbackType | null=null注意,TSLint会抱怨“TSLint:Interface只有一个调用签名-改用
    typemyhandler=(myArgument:string)=>void
    (可调用类型)”;看,这个答案的早期草稿实际上解决了导致我提出这个问题的问题。我一直试图在一个接口中定义一个足够允许的函数签名,该接口可以接受任意数量的参数,而不会产生编译器错误。我的答案是使用
    …args:any[]
    。示例:导出接口MyInterface{/**A回调函数。/callback:(…args:any[])=>any,/*回调函数的参数。*/callbackParams:any[]}我在哪里可以找到此文档?@E.Sundin-While true and nice to know,同一页的“Type alias”部分(现在)还声明“因为软件的一个理想属性是开放扩展的,所以如果可能的话,您应该始终在类型别名上使用接口。”@Arjan-我完全同意对象的这一点。您可以指定-您希望如何扩展函数吗?请注意,类型声明是可选的:
    var handler:(myArgument:string)=>void
    在语法上有效(如果有点混乱)。我不明白为什么定义回调签名需要参数名…我想可能是一些,我想我还是喜欢它…@nikeee你能提供一个指向文档页面的链接吗?这可能是一个很好的链接。但是其他类在哪里运行?