web-dev-qa-db-fra.com

Typescript: Comment définir le type d'un rappel de fonction utilisé (comme n'importe quel type de fonction et non comme universel) utilisé dans un paramètre de méthode

Actuellement, j'ai la définition du type comme:

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

J'ai besoin de quelque chose comme:

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

mais le second n'est pas accepté.

223
Smrutiranjan Sahu

Le type global Function sert cet objectif.

De plus, si vous prévoyez d'appeler ce rappel avec 0 argument et que vous ignorez sa valeur de retour, le type () => void correspond à toutes les fonctions ne prenant aucun argument.

213
Ryan Cavanaugh

TypeScript de v1.4 a le mot clé type qui déclare un alias de type (analogue à un typedef en C/C++). Vous pouvez déclarer votre type de rappel ainsi:

type CallbackFunction = () => void;

qui déclare une fonction qui ne prend aucun argument et ne retourne rien. Une fonction qui prend zéro ou plus d'arguments de tout type et ne renvoie rien serait:

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

Ensuite, vous pouvez dire, par exemple,

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

Si vous voulez une fonction qui prend un nombre arbitraire d'arguments et renvoie quoi que ce soit (y compris void):

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

Vous pouvez spécifier des arguments obligatoires, puis un ensemble d'arguments supplémentaires (par exemple, une chaîne, un nombre puis un ensemble d'arguments supplémentaires), ainsi:

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

Cela peut être utile pour des choses comme les gestionnaires EventEmitter.

Les fonctions peuvent être dactylographiées aussi fort que vous le souhaitez de cette façon, mais vous pouvez vous laisser emporter par des problèmes de combinatoire si vous essayez de tout détruire avec un alias de type.

144
David G

D'après la réponse de Ryan, je pense que l'interface que vous recherchez est définie comme suit:

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

Voici un exemple de fonction qui accepte un rappel

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 vous ne vous souciez pas des valeurs de retour des rappels (la plupart des gens ne savent pas comment les utiliser de manière efficace), vous pouvez utiliser 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
});

Remarque, la signature que j'ai utilisée pour le paramètre callback ...

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

Je dirais que ceci est une déficience de TypeScript car nous sommes supposés fournir un nom pour les paramètres de rappel. Dans ce cas, j'ai utilisé _ parce que ce n'est pas utilisable dans la fonction sqk.

Cependant, si vous faites cela

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

C'est valide TypeScript, mais il sera interprété comme ...

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

C'est-à-dire que TypeScript pensera que le paramètre name est number et que le type impliqué est any. Ce n’est évidemment pas ce que nous voulions, mais hélas, c’est comme ça que TypeScript fonctionne.

Donc, n'oubliez pas de fournir les noms de paramètres lors de la saisie des paramètres de votre fonction ... aussi stupide que cela puisse paraître.

27
user633183

Vous pouvez définir un type de fonction dans l'interface de différentes manières,

  1. manière générale:
export interface IParam {
  title: string;
  callback(arg1: number, arg2: number): number;
}
  1. Si vous souhaitez utiliser la syntaxe de la propriété, alors,
export interface IParam {
  title: string;
  callback: (arg1: number, arg2: number) => number;
}
  1. Si vous déclarez d'abord le type de fonction,
type MyFnType = (arg1: number, arg2: number) => number;

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

L'utilisation est très simple,

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

    return result;
}
  1. Vous pouvez également déclarer un type de fonction littéral, ce qui signifie qu'une fonction peut accepter une autre fonction en tant que paramètre. La fonction de paramétrage peut également être appelée en tant que rappel.
export interface IParam{
  title: string;
  callback(lateCallFn?:
             (arg1:number,arg2:number)=>number):number;

}
15
Humayoun_Kabir