Actualmente tengo la definición de tipo como:
interface Param {
title: string;
callback: any;
}
Necesito algo como:
interface Param {
title: string;
callback: function;
}
pero el segundo no está siendo aceptado.
Actualmente tengo la definición de tipo como:
interface Param {
title: string;
callback: any;
}
Necesito algo como:
interface Param {
title: string;
callback: function;
}
pero el segundo no está siendo aceptado.
Respuestas:
El tipo global Function
sirve para este propósito.
Además, si tiene la intención de invocar esta devolución de llamada con 0 argumentos e ignorará su valor de retorno, el tipo () => void
coincide con todas las funciones sin tomar argumentos.
Function
como se muestra en la primera línea de esta respuesta, y dice que () => void
se prefiere el segundo párrafo (usando el tipo de o lo que coincida con el caso de uso)?
El mecanografiado de v1.4 tiene la type
palabra clave que declara un alias de tipo (análogo a a typedef
en C / C ++). Puede declarar su tipo de devolución de llamada así:
type CallbackFunction = () => void;
que declara una función que no toma argumentos y no devuelve nada. Una función que toma cero o más argumentos de cualquier tipo y no devuelve nada sería:
type CallbackFunctionVariadic = (...args: any[]) => void;
Entonces puedes decir, por ejemplo,
let callback: CallbackFunctionVariadic = function(...args: any[]) {
// do some stuff
};
Si desea una función que tome un número arbitrario de argumentos y devuelva cualquier cosa (incluido void)
type CallbackFunctionVariadicAnyReturn = (...args: any[]) => any;
Puede especificar algunos argumentos obligatorios y luego un conjunto de argumentos adicionales (digamos una cadena, un número y luego un conjunto de argumentos adicionales) así:
type CallbackFunctionSomeVariadic =
(arg1: string, arg2: number, ...args: any[]) => void;
Esto puede ser útil para cosas como los controladores EventEmitter.
Las funciones se pueden escribir tan fuertemente como desee de esta manera, aunque puede dejarse llevar y tener problemas combinatorios si trata de precisar todo con un alias de tipo.
Function
y (...args: any[]) => any
qué se prefiere?
...args: any[]
No es muy útil.
type CallbackFunctionSomeVariadic = (arg1: string, arg2: number, ...args: any[]) => void;
Lo que estaba buscando, Ty.
Aquí hay un ejemplo de una función que acepta una devolución de llamada
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
});
Si no le importan los valores de retorno de las devoluciones de llamada (la mayoría de las personas no saben cómo utilizarlas de manera efectiva), puede usar 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
});
Tenga en cuenta que la firma que utilicé para el callback
parámetro ...
const sqk = (x: number, callback: ((_: number) => number)): number
Yo diría que esto es una deficiencia de TypeScript porque se espera que proporcionemos un nombre para los parámetros de devolución de llamada. En este caso lo usé _
porque no se puede usar dentro de la sqk
función.
Sin embargo, si haces esto
// danger!! don't do this
const sqk = (x: number, callback: ((number) => number)): number
Es TypeScript válido , pero se interpretará como ...
// watch out! typescript will think it means ...
const sqk = (x: number, callback: ((number: any) => number)): number
Es decir, TypeScript pensará que el nombre del parámetro es number
y el tipo implícito es any
. Obviamente, esto no es lo que pretendíamos, pero, por desgracia, así es como funciona TypeScript.
Así que no olvides proporcionar los nombres de los parámetros al escribir los parámetros de tu función ... por estúpido que parezca.
Puede definir un tipo de función en la interfaz de varias maneras,
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;
}
Usar es muy sencillo,
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;
}
Hay cuatro tipos de funciones abstractas, puede usarlas por separado cuando sepa que su función tomará un argumento o no, devolverá un dato o no.
export declare type fEmptyVoid = () => void;
export declare type fEmptyReturn = () => any;
export declare type fArgVoid = (...args: any[]) => void;
export declare type fArgReturn = (...args: any[]) => any;
Me gusta esto:
public isValid: fEmptyReturn = (): boolean => true;
public setStatus: fArgVoid = (status: boolean): void => this.status = status;
Para usar solo un tipo como cualquier tipo de función, podemos combinar todos los tipos abstractos juntos, así:
export declare type fFunction = fEmptyVoid | fEmptyReturn | fArgVoid | fArgReturn;
luego úsalo como:
public isValid: fFunction = (): boolean => true;
public setStatus: fFunction = (status: boolean): void => this.status = status;
En el ejemplo anterior, todo es correcto. Pero el ejemplo de uso a continuación no es correcto desde el punto de vista de la mayoría de los editores de código.
// 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();
}
La llamada correcta para los editores es así:
public callArgument(callback: fFunction) {
// pay attention in this part, for fix editor(s) error
(callback as fFunction)();
}
Mecanografiado: ¿Cómo definir el tipo para una devolución de llamada de función utilizada en un parámetro de método ?
Puede declarar la devolución de llamada como 1) propiedad de función o 2) método :
interface ParamFnProp {
callback: (a: Animal) => void; // function property
}
interface ParamMethod {
callback(a: Animal): void; // method
}
Hay una diferencia de tipeo importante desde TS 2.6 :
Obtiene tipos más fuertes ("sonido") en --strict
o --strictFunctionTypes
modo, cuando se declara una propiedad de función . Tomemos un ejemplo:
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 ...
Técnicamente hablando, los métodos son bivariantes y las propiedades de la función son contravariantes en sus argumentos bajo strictFunctionTypes
. Los métodos aún se verifican de manera más permisiva (incluso si no suena) para que sean un poco más prácticos en combinación con tipos incorporados como Array
.