Javascript 如何为方法参数中使用的函数回调定义类型(作为任何函数类型,而不是通用类型)

Javascript 如何为方法参数中使用的函数回调定义类型(作为任何函数类型,而不是通用类型),javascript,typescript,Javascript,Typescript,目前,我的类型定义为: interface Param { title: string; callback: any; } 我需要像这样的东西: interface Param { title: string; callback: function; } 但是第二个不被接受。全局类型函数用于此目的 此外,如果您打算使用0个参数调用此回调函数并忽略其返回值,则类型()=>void将匹配所有不带参数的函数。根据Ryan的回答,我认为您要查找的接口定义如下: int

目前,我的类型定义为:

interface Param {
    title: string;
    callback: any;
}
我需要像这样的东西:

interface Param {
    title: string;
    callback: function;
}

但是第二个不被接受。

全局类型
函数
用于此目的


此外,如果您打算使用0个参数调用此回调函数并忽略其返回值,则类型
()=>void
将匹配所有不带参数的函数。

根据Ryan的回答,我认为您要查找的接口定义如下:

interface Param {
    title: string;
    callback: () => void;
}

v1.4中的Typescript具有声明类型别名的
type
关键字(类似于C/C++中的
typedef
)。您可以这样声明回调类型:

type CallbackFunction = () => void;
它声明了一个不带参数且不返回任何内容的函数。接受任何类型的零个或多个参数且不返回任何内容的函数将是:

type CallbackFunctionVariadic = (...args: any[]) => void;
然后你可以说,比如

let callback: CallbackFunctionVariadic = function(...args: any[]) {
  // do some stuff
};
如果希望函数接受任意数量的参数并返回任何内容(包括void),请执行以下操作:

您可以指定一些强制参数,然后指定一组附加参数(例如字符串、数字,然后是一组附加参数),因此:

这对于EventEmitter处理程序之类的事情很有用


以这种方式,函数可以按您喜欢的强度进行类型化,但如果您试图用类型别名确定所有内容,则可能会得意忘形并遇到组合问题。

下面是一个接受回调的函数示例

const sqk = (x: number, callback: ((_: number) => number)): number => {
  // callback will receive a number and expected to return a number
  return callback (x * x);
}

// here our callback will receive a number
sqk(5, function(x) {
  console.log(x); // 25
  return x;       // we must return a number here
});
如果您不关心回调的返回值(大多数人不知道如何有效地利用它们),那么可以使用
void

const sqk = (x: number, callback: ((_: number) => void)): void => {
  // callback will receive a number, we don't care what it returns
  callback (x * x);
}

// here our callback will receive a number
sqk(5, function(x) {
  console.log(x); // 25
  // void
});
注意,我用于
回调
参数的签名

const sqk = (x: number, callback: ((_: number) => number)): number
这是有效的TypeScript,但它将被解释为

// watch out! typescript will think it means ...
const sqk = (x: number, callback: ((number: any) => number)): number
//小心!typescript会认为这意味着。。。
常量sqk=(x:number,回调:((number:any)=>number)):number
也就是说,TypeScript会认为参数名是
number
,隐含类型是
any
。这显然不是我们想要的,但唉,TypeScript就是这样工作的


因此,在键入函数参数时,不要忘记提供参数名称。。。看起来很愚蠢。

您可以用各种方式在接口中定义函数类型

  • 一般方法:
  • 导出接口IPRAM{
    标题:字符串;
    回调(arg1:number,arg2:number):number;
    }
    
  • 如果要使用属性语法
  • 导出接口IPRAM{
    标题:字符串;
    回调:(arg1:number,arg2:number)=>number;
    }
    
  • 如果先声明函数类型
  • type MyFnType=(arg1:number,arg2:number)=>number;
    导出接口IPRAM{
    标题:字符串;
    回调:MyFnType;
    }
    
    使用非常直接

    function callingFn(paramInfo: IParam):number {
        let needToCall = true;
        let result = 0;
       if(needToCall){
         result = paramInfo.callback(1,2);
        }
    
        return result;
    }
    
  • 您还可以声明函数类型文字,这意味着一个函数可以接受另一个函数作为其参数。参数化函数也可以被称为回调函数
  • 导出接口IPRAM{
    标题:字符串;
    回调(lateCallFn?:
    (arg1:number,arg2:number)=>number:number;
    }
    
    有四种抽象函数类型,当您知道函数是否接受参数、是否返回数据时,可以分别使用它们

    export declare type fEmptyVoid = () => void;
    export declare type fEmptyReturn = () => any;
    export declare type fArgVoid = (...args: any[]) => void;
    export declare type fArgReturn = (...args: any[]) => any;
    
    像这样:

    public isValid: fEmptyReturn = (): boolean => true;
    public setStatus: fArgVoid = (status: boolean): void => this.status = status;
    
    export declare type fFunction = fEmptyVoid | fEmptyReturn | fArgVoid | fArgReturn;
    
    public callArgument(callback: fFunction) {
    
        // pay attention in this part, for fix editor(s) error
        (callback as fFunction)();
    }
    
    对于仅使用一种类型作为任何函数类型,我们可以将所有抽象类型组合在一起,如下所示:

    public isValid: fEmptyReturn = (): boolean => true;
    public setStatus: fArgVoid = (status: boolean): void => this.status = status;
    
    export declare type fFunction = fEmptyVoid | fEmptyReturn | fArgVoid | fArgReturn;
    
    public callArgument(callback: fFunction) {
    
        // pay attention in this part, for fix editor(s) error
        (callback as fFunction)();
    }
    
    然后像这样使用它:

    public isValid: fFunction = (): boolean => true;
    public setStatus: fFunction = (status: boolean): void => this.status = status;
    
    在上面的例子中,一切都是正确的。但从大多数代码编辑器的角度来看,下面的用法示例并不正确

    // you can call this function with any type of function as argument
    public callArgument(callback: fFunction) {
    
        // but you will get editor error if call callback argument like this
        callback();
    }
    
    对编辑器的正确调用如下所示:

    public isValid: fEmptyReturn = (): boolean => true;
    public setStatus: fArgVoid = (status: boolean): void => this.status = status;
    
    export declare type fFunction = fEmptyVoid | fEmptyReturn | fArgVoid | fArgReturn;
    
    public callArgument(callback: fFunction) {
    
        // pay attention in this part, for fix editor(s) error
        (callback as fFunction)();
    }
    
    Typescript:如何为方法参数中使用的函数回调定义类型

    您可以将回调声明为1)函数属性或2)方法:

    有一个重要的类型差异,因为:

    声明函数属性时,在
    --strict
    --strictFunctionTypes
    模式下,您会得到更强的(“声音”)类型。让我们举一个例子:

    const animalCallback = (a: Animal): void => { } // Animal is the base type for Dog
    const dogCallback = (d: Dog): void => { } 
    
    从技术上讲,方法在
    strictFunctionTypes
    下的参数中是双变量和函数属性。与内置类型(如
    Array
    )相结合,方法仍然(即使不健全)更加实用

    总结
    • 函数属性和方法声明之间存在类型差异
    • 如果可能,请为强类型选择函数属性

    希望这将有助于

    interface Param {
        title: string;
        callback: (error: Error, data: string) => void;
    }
    
    
    或者在函数中

    
    let myfunction = (title: string, callback: (error: Error, data: string) => void): string => {
    
        callback(new Error(`Error Message Here.`), "This is callback data.");
        return title;
    
    }
    
    

    我刚刚开始使用Typescript,我一直在尝试解决类似的问题;如何告诉Typescript我正在传递回调,而没有
    接口

    在浏览了一些关于堆栈溢出和GitHub问题的答案之后,我终于找到了一个解决方案,可以帮助任何有同样问题的人

    可以使用
    (arg0:type0)=>returnType
    定义函数的类型,我们可以在另一个函数的参数列表中使用此类型定义

    函数runCallback(callback:(sum:number)=>void,a:number,b:number):void{
    回调(a+b);
    }
    //编写函数的另一种方法是:
    //让logSum:(和:数)=>void=函数(和:数):void{
    //控制台日志(总和);
    // };
    函数对数和(和:数):无效{
    log(`sum是${sum}.`);
    }
    runCallback(logSum,2,2);
    
    中缺少此项,它不是基本类型,因为您应该定义参数并返回值。类似回调:(number:number)=>void;对于类型检查比回调函数更有用;will be.FWIW,关于函数类型的文档在@SgtPooki可用,并且您的编辑非常重要,您确定它们更多地属于编辑而不是您自己的答案吗?我认为你的补充是有效的建议,但鉴于Ryan的权威,我很惊讶在这里发现你的编辑,特别是在他们的地方。