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

时间:2022-03-01 16:33:31

Currently I have type definition as:

目前我的类型定义为:

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

I need something like:

我需要类似:

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

but the 2nd one is not being accepted.

但是第二种是不被接受的。

4 个解决方案

#1


124  

The global type Function serves this purpose.

全局类型函数实现了这个目的。

Additionally, if you intend to invoke this callback with 0 arguments and will ignore its return value, the type () => void matches all functions taking no arguments.

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

#2


71  

Typescript from v1.4 has the type keyword which declares a type alias (analogous to a typedef in C/C++). You can declare your callback type thus:

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

type CallbackFunction = () => void;

which declares a function that takes no arguments and returns nothing. A function that takes zero or more arguments of any type and returns nothing would be:

声明一个不带参数且不返回任何值的函数。任何类型的参数为0或更多且不返回任何值的函数为:

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

Then you can say, for example,

然后你可以说,例如,

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

If you want a function that takes an arbitrary number of arguments and returns anything (including void):

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

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

You can specify some mandatory arguments and then a set of additional arguments (say a string, a number and then a set of extra args) thus:

您可以指定一些强制参数,然后指定一组附加参数(例如一个字符串、一个数字和一组额外的args),从而:

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

This can be useful for things like EventEmitter handlers.

这对于事件发射器处理程序之类的东西是有用的。

Functions can be typed as strongly as you like in this fashion, although you can get carried away and run into combinatoric problems if you try to nail everything down with a type alias.

函数可以按照这种方式进行强类型输入,但是如果您试图用类型别名将所有内容都确定下来,那么您可能会感到迷惑,并遇到组合问题。

#3


33  

Following from Ryan's answer, I think that the interface you are looking for is defined as follows:

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

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

#4


14  

Here's an example of a function that accepts a callback

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

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

If you don't care about the return values of callbacks (most people don't know how to utilize them in any effective way), you can use void

如果您不关心回调的返回值(大多数人不知道如何有效地利用它们),那么可以使用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
});

Note, the signature I used for the callback parameter ...

注意,我用于回调参数的签名…

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

I would say this is a TypeScript deficiency because we are expected to provide a name for the callback parameters. In this case I used _ because it's not usable inside the sqk function.

我认为这是一个打字稿缺陷,因为我们需要为回调参数提供一个名称。在这个例子中,我用了_因为它在sqk函数中不能用。

However, if you do this

但是,如果你这样做的话

// danger!! don't do this
const sqk = (x: number, callback: ((number) => number)): number

It's valid TypeScript, but it will interpreted as ...

这是有效的打字稿,但它将被解释为……

// watch out! typescript will think it means ...
const sqk = (x: number, callback: ((number: any) => number)): number

Ie, TypeScript will think the parameter name is number and the implied type is any. This is obviously not what we intended, but alas, that is how TypeScript works.

比如,TypeScript会认为参数名是number,隐含类型是any。这显然不是我们想要的,但是,唉,这就是打字稿的工作方式。

So don't forget to provide the parameter names when typing your function parameters... stupid as it might seem.

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

#1


124  

The global type Function serves this purpose.

全局类型函数实现了这个目的。

Additionally, if you intend to invoke this callback with 0 arguments and will ignore its return value, the type () => void matches all functions taking no arguments.

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

#2


71  

Typescript from v1.4 has the type keyword which declares a type alias (analogous to a typedef in C/C++). You can declare your callback type thus:

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

type CallbackFunction = () => void;

which declares a function that takes no arguments and returns nothing. A function that takes zero or more arguments of any type and returns nothing would be:

声明一个不带参数且不返回任何值的函数。任何类型的参数为0或更多且不返回任何值的函数为:

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

Then you can say, for example,

然后你可以说,例如,

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

If you want a function that takes an arbitrary number of arguments and returns anything (including void):

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

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

You can specify some mandatory arguments and then a set of additional arguments (say a string, a number and then a set of extra args) thus:

您可以指定一些强制参数,然后指定一组附加参数(例如一个字符串、一个数字和一组额外的args),从而:

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

This can be useful for things like EventEmitter handlers.

这对于事件发射器处理程序之类的东西是有用的。

Functions can be typed as strongly as you like in this fashion, although you can get carried away and run into combinatoric problems if you try to nail everything down with a type alias.

函数可以按照这种方式进行强类型输入,但是如果您试图用类型别名将所有内容都确定下来,那么您可能会感到迷惑,并遇到组合问题。

#3


33  

Following from Ryan's answer, I think that the interface you are looking for is defined as follows:

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

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

#4


14  

Here's an example of a function that accepts a callback

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

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

If you don't care about the return values of callbacks (most people don't know how to utilize them in any effective way), you can use void

如果您不关心回调的返回值(大多数人不知道如何有效地利用它们),那么可以使用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
});

Note, the signature I used for the callback parameter ...

注意,我用于回调参数的签名…

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

I would say this is a TypeScript deficiency because we are expected to provide a name for the callback parameters. In this case I used _ because it's not usable inside the sqk function.

我认为这是一个打字稿缺陷,因为我们需要为回调参数提供一个名称。在这个例子中,我用了_因为它在sqk函数中不能用。

However, if you do this

但是,如果你这样做的话

// danger!! don't do this
const sqk = (x: number, callback: ((number) => number)): number

It's valid TypeScript, but it will interpreted as ...

这是有效的打字稿,但它将被解释为……

// watch out! typescript will think it means ...
const sqk = (x: number, callback: ((number: any) => number)): number

Ie, TypeScript will think the parameter name is number and the implied type is any. This is obviously not what we intended, but alas, that is how TypeScript works.

比如,TypeScript会认为参数名是number,隐含类型是any。这显然不是我们想要的,但是,唉,这就是打字稿的工作方式。

So don't forget to provide the parameter names when typing your function parameters... stupid as it might seem.

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