目前我的类型定义为:
interface Param {
title: string;
callback: any;
}
我需要类似的东西:
interface Param {
title: string;
callback: function;
}
但第二个不被接受。
callback:Function
而不是 lower case callback:function
Function
不兼容是一种情况,所以我创建了一个“AnyFunction”类型:export type AnyFunction = (...args: any[]) => any;
全局类型 Function
用于此目的。
此外,如果您打算使用 0 个参数调用此回调并忽略其返回值,则类型 () => 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)的函数:
type CallbackFunctionVariadicAnyReturn = (...args: any[]) => any;
您可以指定一些强制参数,然后指定一组附加参数(比如一个字符串、一个数字,然后是一组额外的参数),因此:
type CallbackFunctionSomeVariadic =
(arg1: string, arg2: number, ...args: any[]) => void;
这对于诸如 EventEmitter 处理程序之类的东西很有用。
可以用这种方式对函数进行任意强度的类型化,但如果您尝试使用类型别名来确定所有内容,您可能会被带走并遇到组合问题。
Function
和 (...args: any[]) => any
之间首选什么?
...args: any[]
不是很有用。
type CallbackFunctionSomeVariadic = (arg1: string, arg2: number, ...args: any[]) => void;
我在寻找什么,ty。
export type CallbackFunctionSomething = (page: number, sort: blablabla) => void
Function
和 (...args: any[]) => any
不一样
根据 Ryan 的回答,我认为您正在寻找的界面定义如下:
interface Param {
title: string;
callback: () => void;
}
您可以通过各种方式在接口中定义函数类型,
一般方式:
export interface IParam {
title: string;
callback(arg1: number, arg2: number): number;
}
如果您想使用属性语法,
export interface IParam {
title: string;
callback: (arg1: number, arg2: number) => number;
}
如果你先声明函数类型,
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;
}
你也可以声明一个函数类型文字,这意味着一个函数可以接受另一个函数作为它的参数。参数化函数也可以作为回调调用。
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 的缺陷,因为我们需要为回调参数提供一个 name。在这种情况下,我使用了 _
,因为它在 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 会认为参数 name 是 number
,隐含类型是 any
。这显然不是我们想要的,但可惜的是,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 ESLint plugin 具有推荐的规则 ban-types(错误)和 no-explicit-any(警告)。
避免使用 Function 类型,因为它提供的安全性很小
遵守这些规则,也许最好的解决方案是,
callback: (...args: unknown[]) => unknown
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
下的参数中是双变量和函数属性 contravariant。方法仍然是 checked more permissively(即使不健全)与 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 我正在传递一个没有 interface
的回调。
在浏览了一些关于 Stack Overflow 和 GitHub 问题的答案后,我终于找到了一个可以帮助任何有同样问题的人的解决方案。
一个函数的类型可以用 (arg0: type0) => returnType
定义,我们可以在另一个函数的参数列表中使用这个类型定义。
function runCallback(callback: (sum: number) => void, a: number, b: number): void {
callback(a + b);
}
// Another way of writing the function would be:
// let logSum: (sum: number) => void = function(sum: number): void {
// console.log(sum);
// };
function logSum(sum: number): void {
console.log(`The sum is ${sum}.`);
}
runCallback(logSum, 2, 2);
Function
直接作为类型 -- 引用“不要使用Function
作为类型。Function
类型接受任何类似函数的值。它在调用函数时不提供类型安全,它可以是常见的错误来源。它还接受诸如类声明之类的东西,它们将在运行时抛出,因为它们不会被new
调用。”