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

2020/10/02 05:01 · javascript ·  · 0评论

目前,我的类型定义为:

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

我需要类似的东西:

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

但第二个不被接受。

全局类型Function用于此目的。

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


更新详细信息和改进。

这里的答案和问题有太多不足之处,更不用说唯一稍微复杂一点但最佳实践的方法了:

解决您的问题

interface Easy_Fix_Solution {
    title: string;
    callback: Function;
}

注意:请不要使用,Function因为您很可能不希望使用any回调函数。可以具体一点。

对该解决方案的改进

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

注意:原始作者是正确的,不接受任何参数,并且返回void更好。.它更安全,它告诉您接口的使用者您将不会对其返回值做任何事情,并且也不会传递它们任何值。参数。

更好的是
使用泛型。
该接口还可以用于
() => void前面提到的相同功能类型。

interface Better_still_safe_but_way_more_flexible_fix {
    title: string;
    callback: <T = unknown, R = unknown>(args?: T) => R;
}
interface Alternate_Syntax_4_Better_still_safe_but_way_more_flexible_fix {
    title: string;
    callback<T = unknown, R = unknown>(args?: T): R;
}

注意:如果您现在还不能100%确定回调签名,请选择上面的void选项,如果您认为将来可能扩展功能,请选择此通用选项。回调通常会接收某种形式的参数,有时回调协调器甚至会使用返回值执行某些操作。

还有一个更高级的用例,除非需要,否则不应该使用

这允许在T中使用任意数量的任何类型的参数。

更多细节在这里

interface Alternate_Syntax_4_Advanced {
    title: string;
    callback<T extends unknown[], R = unknown>(...args?: T): R;
}

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

type CallbackFunction = () => void;

它声明一个不带参数且不返回任何值的函数。接受零个或多个任何类型的参数且不返回任何值的函数将是:

type CallbackFunctionVariadic = (...args: any[]) => void;

然后您可以说,例如

let callback: CallbackFunctionVariadic = function(...args: any[]) {
  // do some stuff
};

如果您想要一个函数,它接受任意数量的参数并返回任何值(包括void):

type CallbackFunctionVariadicAnyReturn = (...args: any[]) => any;

您可以指定一些强制性参数,然后指定一组其他参数(例如,字符串,数字,然后是一组额外的参数):

type CallbackFunctionSomeVariadic =
  (arg1: string, arg2: number, ...args: any[]) => void;

这对于诸如EventEmitter处理程序之类的东西可能很有用。

可以按这种方式随意键入函数,尽管如果尝试使用类型别名将所有内容都弄清楚,则可能会被带走并遇到组合问题。

根据Ryan的回答,我认为您正在寻找的接口定义如下:

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

您可以通过多种方式在接口中定义函数类型,

  1. 一般方式:
export interface IParam {
  title: string;
  callback(arg1: number, arg2: number): number;
}
  1. 如果您想使用属性语法,
export interface IParam {
  title: string;
  callback: (arg1: number, arg2: number) => number;
}
  1. 如果您先声明函数类型,
type MyFnType = (arg1: number, arg2: number) => number;

export interface IParam {
  title: string;
  callback: MyFnType;
}

使用非常简单

function callingFn(paramInfo: IParam):number {
    let needToCall = true;
    let result = 0;
   if(needToCall){
     result = paramInfo.callback(1,2);
    }

    return result;
}
  1. 您还可以声明一个函数类型文字,这意味着一个函数可以接受另一个函数作为其参数。参数化函数也可以称为回调。
export interface IParam{
  title: string;
  callback(lateCallFn?:
             (arg1:number,arg2:number)=>number):number;

}

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

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

注意,我用于callback参数的签名...

const sqk = (x: number, callback: ((_: number) => number)): number

我会说这是TypeScript的缺陷,因为我们希望为回调参数提供一个名称在这种情况下,我使用了_它,因为它在sqk函数内部不可用

但是,如果您这样做

// danger!! don't do this
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会认为参数名称number,而隐含类型为any这显然不是我们想要的,但是,a,TypeScript是这样工作的。

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

共有四种抽象函数类型,当您知道函数将使用或不使用参数,是否将返回数据时,可以分别使用它们。

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 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 callArgument(callback: fFunction) {

    // pay attention in this part, for fix editor(s) error
    (callback as fFunction)();
}

Typescript:如何为方法参数中使用的函数回调定义类型

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

interface ParamFnProp {
    callback: (a: Animal) => void; // function property
}

interface ParamMethod {
    callback(a: Animal): void; // method
}

TS 2.6存在重要的输入区别

声明功能属性后您将在--strict--strictFunctionTypes模式下获得更强的(“声音”)类型让我们举个例子:

const animalCallback = (a: Animal): void => { } // Animal is the base type for Dog
const dogCallback = (d: Dog): void => { } 
// function property variant
const param11: ParamFnProp = { callback: dogCallback } // error: not assignable
const param12: ParamFnProp = { callback: animalCallback } // works

// method variant
const param2: ParamMethod = { callback: dogCallback } // now it works again ...

从技术上说,方法是双变量和函数属性逆变下他们的观点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;

}

本文地址:http://javascript.askforanswer.com/typescriptruheweifangfacanshuzhongshiyongdehanshuhuidiaodingyileixingzuoweirenhehanshuleixing.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!