Het type definiëren voor een functieaanroep (als elk functietype, niet universeel) dat wordt gebruikt in een methodeparameter

Momenteel heb ik typedefinitie als:

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

Ik heb iets nodig als:

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

maar de 2e wordt niet geaccepteerd.


Antwoord 1, autoriteit 100%

Het algemene type Functiondient dit doel.

Bovendien, als u van plan bent deze callback aan te roepen met 0 argumenten en de geretourneerde waarde negeert, moet het type () => voidkomt overeen met alle functies zonder argumenten.


Antwoord 2, autoriteit 54%

Typescript van v1.4 heeft het trefwoord typedat een type-alias declareert (analoog aan een typedefin C/C++). U kunt uw terugbeltype als volgt declareren:

type CallbackFunction = () => void;

die een functie declareert die geen argumenten nodig heeft en niets retourneert. Een functie die nul of meer argumenten van elk type nodig heeft en niets teruggeeft, zou zijn:

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

Dan kun je bijvoorbeeld zeggen:

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

Als je een functie wilt die een willekeurig aantal argumenten nodig heeft en alles retourneert (inclusief void):

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

U kunt enkele verplichte argumenten opgeven en vervolgens een reeks aanvullende argumenten (bijvoorbeeld een string, een getal en vervolgens een reeks extra args) zeggen) dus:

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

Dit kan handig zijn voor zaken als gebeurtenistermitter-handlers.

Functies kunnen zo sterk worden getypt als u op deze manier wilt, hoewel u zich kunt laten meeslepen en in combinatorische problemen kunt uitvoeren als u alles neergaat met een type alias.


Antwoord 3, Autoriteit 17%

Opvolgen van het antwoord van Ryan, denk ik dat de interface die u zoekt, als volgt is gedefinieerd:

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

Antwoord 4, Autoriteit 10%

U kunt op verschillende manieren een functietype in-interface definiëren,

  1. algemene manier:
export interface IParam {
  title: string;
  callback(arg1: number, arg2: number): number;
}
  1. Als u vervolgens een eigendomssyntaxis wilt gebruiken,
export interface IParam {
  title: string;
  callback: (arg1: number, arg2: number) => number;
}
  1. Als u eerst het functietype declareert,
type MyFnType = (arg1: number, arg2: number) => number;
export interface IParam {
  title: string;
  callback: MyFnType;
}

Het gebruik is heel eenvoudig,

function callingFn(paramInfo: IParam):number {
    let needToCall = true;
    let result = 0;
   if(needToCall){
     result = paramInfo.callback(1,2);
    }
    return result;
}
  1. Je kunt een functietype ook letterlijk declareren, wat betekent dat een functie een andere functie als parameter kan accepteren. parameterize functie kan ook worden aangeroepen als callback.
export interface IParam{
  title: string;
  callback(lateCallFn?:
             (arg1:number,arg2:number)=>number):number;
}

Antwoord 5, autoriteit 8%

Hier is een voorbeeld van een functie die een callback accepteert

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

Als u niet geïnteresseerd bent in de retourwaarden van callbacks (de meeste mensen weten niet hoe ze deze op een effectieve manier kunnen gebruiken), kunt u void

gebruiken

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

Let op, de handtekening die ik heb gebruikt voor de parameter callback

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

Ik zou zeggen dat dit een TypeScript-tekort is, omdat er van ons wordt verwacht dat we een naamopgeven voor de callback-parameters. In dit geval heb ik _gebruikt omdat het niet bruikbaar is binnen de functie sqk.

Als u dit echter doet

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

Het is geldigTypeScript, maar het wordt geïnterpreteerd als …

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

Dat wil zeggen, TypeScript denkt dat de parameter naamnumberis en dat het impliciete type anyis. Dit is natuurlijk niet wat we bedoelden, maar helaas, zo werkt TypeScript.

Vergeet dus niet de parameternamen op te geven bij het typen van uw functieparameters… hoe dom het ook lijkt.


Antwoord 6, autoriteit 4%

Er zijn vier abstracte functietypes, je kunt ze afzonderlijk gebruiken als je weet dat je functie een of meer argumenten zal aannemen of niet, een data zal retourneren of niet.

export declare type fEmptyVoid = () => void;
export declare type fEmptyReturn = () => any;
export declare type fArgVoid = (...args: any[]) => void;
export declare type fArgReturn = (...args: any[]) => any;

zoals dit:

public isValid: fEmptyReturn = (): boolean => true;
public setStatus: fArgVoid = (status: boolean): void => this.status = status;

Om slechts één type te gebruiken als elk functietype kunnen we alle abstracte typen samen combineren, zoals dit:

export declare type fFunction = fEmptyVoid | fEmptyReturn | fArgVoid | fArgReturn;

gebruik het dan als volgt:

public isValid: fFunction = (): boolean => true;
public setStatus: fFunction = (status: boolean): void => this.status = status;

In het bovenstaande voorbeeld is alles correct. Maar het gebruiksvoorbeeld hieronder is niet correct vanuit het oogpunt van de meeste 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();
}

De juiste oproep voor redacteuren is als volgt:

public callArgument(callback: fFunction) {
    // pay attention in this part, for fix editor(s) error
    (callback as fFunction)();
}

Antwoord 7

Typescript: hoe definieer je het type voor een functieaanroep die wordt gebruikt in een methodeparameter?

U kunt de callback declareren als 1) functie-eigenschapof 2) methode:

interface ParamFnProp {
    callback: (a: Animal) => void; // function property
}
interface ParamMethod {
    callback(a: Animal): void; // method
}

Er is een belangrijk typischverschil sinds TS 2.6:

Je krijgt sterkere (“geluid”) typen in de modus --strictof --strictFunctionTypes, wanneer een functie-eigenschapwordt gedeclareerd. Laten we een voorbeeld nemen:

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 ...

Technisch gesproken zijn methoden bivarianten functie-eigenschappen contravariantin hun argumenten onder strictFunctionTypes. Methoden worden nog steeds permissiever gecontroleerd(zelfs zo niet geluid) om wat praktischer te zijn in combinatie met ingebouwde typen zoals Array.

Samenvatting

  • Er is een typeverschil tussen functie-eigenschap en methodedeclaratie
  • Kies indien mogelijk een functie-eigenschap voor sterkere typen

speelplaats steekproefcode


Antwoord 8

Hopelijk zal dit helpen …

interface Param {
    title: string;
    callback: (error: Error, data: string) => void;
}

of in een functie


let myfunction = (title: string, callback: (error: Error, data: string) => void): string => {
    callback(new Error(`Error Message Here.`), "This is callback data.");
    return title;
}

Antwoord 9

Ik ben net begonnen met het gebruik van typescript en ik heb geprobeerd een soortgelijk probleem op te lossen; Hoe het typescript te vertellen dat ik een callback passeer zonder een interface.

Na het bladeren van een paar antwoorden op stapeloverloop en GitHub-problemen, vond ik eindelijk een oplossing die iedereen met hetzelfde probleem kan helpen.

Het type van een functie kan worden gedefinieerd met (arg0: type0) => returnTypeEn we kunnen deze typedfinitie gebruiken in de parameterlijst van een andere functie.

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

Other episodes