Javascript 打字稿:如何为方法参数中使用的函数回调定义类型(作为任何函数类型,不是通用的)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29689966/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Typescript: How to define type for a function callback (as any function type, not universal any) used in a method parameter
提问by Smrutiranjan Sahu
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.
但第二个没有被接受。
回答by Ryan Cavanaugh
The global type Functionserves this purpose.
全局类型Function用于此目的。
Additionally, if you intend to invoke this callback with 0 arguments and will ignore its return value, the type () => voidmatches all functions taking no arguments.
此外,如果您打算使用 0 个参数调用此回调并忽略其返回值,则该类型() => void匹配所有不带参数的函数。
回答by David G
Typescript from v1.4 has the typekeyword which declares a type alias (analogous to a typedefin C/C++). You can declare your callback type thus:
v1.4 中的 Typescript 具有type声明类型别名的关键字(类似于typedefC/C++ 中的 a)。您可以这样声明您的回调类型:
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:
它声明了一个不带参数且不返回任何内容的函数。接受零个或多个任何类型的参数并且不返回任何内容的函数将是:
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:
您可以指定一些强制性参数,然后是一组附加参数(比如一个字符串、一个数字,然后是一组额外的参数),因此:
type CallbackFunctionSomeVariadic =
(arg1: string, arg2: number, ...args: any[]) => void;
This can be useful for things like EventEmitter handlers.
这对于诸如 EventEmitter 处理程序之类的东西很有用。
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.
函数可以以这种方式按您喜欢的强类型进行输入,但是如果您尝试使用类型别名来确定所有内容,则可能会被带走并遇到组合问题。
回答by blorkfish
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;
}
回答by Thank you
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 callbackparameter ...
请注意,我用于callback参数的签名...
const sqk = (x: number, callback: ((_: number) => number)): number
I would say this is a TypeScript deficiency because we are expected to provide a namefor the callback parameters. In this case I used _because it's not usable inside the sqkfunction.
我会说这是 TypeScript 的缺陷,因为我们需要为回调参数提供一个名称。在这种情况下,我使用_它是因为它在sqk函数内部不可用。
However, if you do this
然而,如果你这样做
// danger!! don't do this
const sqk = (x: number, callback: ((number) => number)): number
It's validTypeScript, but it will interpreted as ...
它是有效的TypeScript,但它会被解释为 ...
// watch out! typescript will think it means ...
const sqk = (x: number, callback: ((number: any) => number)): number
Ie, TypeScript will think the parameter nameis numberand the implied type is any. This is obviously not what we intended, but alas, that is how TypeScript works.
即,TypeScript 会认为参数名称是number,隐含类型是any。这显然不是我们想要的,但是,这就是 TypeScript 的工作方式。
So don't forget to provide the parameter names when typing your function parameters... stupid as it might seem.
所以不要忘记在输入函数参数时提供参数名称......看起来很愚蠢。
回答by Humayoun_Kabir
You can define a function type in interface in various ways,
您可以通过多种方式在接口中定义函数类型,
- general way:
- 一般方式:
export interface IParam {
title: string;
callback(arg1: number, arg2: number): number;
}
- If you would like to use property syntax then,
- 如果你想使用属性语法,那么
export interface IParam {
title: string;
callback: (arg1: number, arg2: number) => number;
}
- If you declare the function type first then,
- 如果先声明函数类型,则
type MyFnType = (arg1: number, arg2: number) => number;
export interface IParam {
title: string;
callback: MyFnType;
}
Using is very straight forward,
使用非常简单,
function callingFn(paramInfo: IParam):number {
let needToCall = true;
let result = 0;
if(needToCall){
result = paramInfo.callback(1,2);
}
return result;
}
- You can declare a function type literal also , which mean a function can accept another function as it's parameter. parameterize function can be called as callback also.
- 你也可以声明一个函数类型文字,这意味着一个函数可以接受另一个函数作为它的参数。参数化函数也可以作为回调调用。
export interface IParam{
title: string;
callback(lateCallFn?:
(arg1:number,arg2:number)=>number):number;
}
回答by Artur T
There are four abstract function types, you can use them separately when you know your function will take an argument(s) or not, will return a data or not.
有四种抽象函数类型,当您知道您的函数是否接受参数、是否返回数据时,您可以分别使用它们。
export declare type fEmptyVoid = () => void;
export declare type fEmptyReturn = () => any;
export declare type fArgVoid = (...args: any[]) => void;
export declare type fArgReturn = (...args: any[]) => any;
like this:
像这样:
public isValid: fEmptyReturn = (): boolean => true;
public setStatus: fArgVoid = (status: boolean): void => this.status = status;
For use only one type as any function type we can combine all abstract types together, like this:
为了仅使用一种类型作为任何函数类型,我们可以将所有抽象类型组合在一起,如下所示:
export declare type fFunction = fEmptyVoid | fEmptyReturn | fArgVoid | fArgReturn;
then use it like:
然后像这样使用它:
public isValid: fFunction = (): boolean => true;
public setStatus: fFunction = (status: boolean): void => this.status = status;
In the example above everything is correct. But the usage example in bellow is not correct from the point of view of most code editors.
在上面的例子中,一切都是正确的。但是从大多数代码编辑器的角度来看,下面的用法示例是不正确的。
// 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();
}
Correct call for editors is like this:
正确的编辑调用是这样的:
public callArgument(callback: fFunction) {
// pay attention in this part, for fix editor(s) error
(callback as fFunction)();
}
回答by ford04
Typescript: How to define type for a function callback used in a methodparameter?
打字稿:如何为方法参数中使用的函数回调定义类型?
You can declare the callback as 1) function propertyor 2) method:
您可以将回调声明为 1)函数属性或 2)方法:
interface ParamFnProp {
callback: (a: Animal) => void; // function property
}
interface ParamMethod {
callback(a: Animal): void; // method
}
There is an important typingdifference since TS 2.6:
自TS 2.6以来,有一个重要的类型差异:
You get stronger ("sound") types in --strictor --strictFunctionTypesmode, when a function propertyis declared. Let's take an example:
当一个函数属性被声明时,你会在--strictor--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 ...
Technically spoken, methods are bivariantand function properties contravariantin their arguments under strictFunctionTypes. Methods are still checked more permissively(even if not sound) to be a bit more practical in combination with built-in types like Array.
从技术上说,方法是双变量和函数属性逆变下他们的观点strictFunctionTypes。方法仍然是检查更permissively(即使没有声音),以更实际相结合的位与内置类型一样Array。
Summary
概括
- There is a type difference between function property and method declaration
- Choose a function property for stronger types, if possible
- 函数属性和方法声明之间存在类型差异
- 如果可能,为更强的类型选择一个函数属性

