Derzeit habe ich eine Typdefinition als:
interface Param {
title: string;
callback: any;
}
Ich brauche so etwas wie:
interface Param {
title: string;
callback: function;
}
aber der 2. wird nicht akzeptiert.
Derzeit habe ich eine Typdefinition als:
interface Param {
title: string;
callback: any;
}
Ich brauche so etwas wie:
interface Param {
title: string;
callback: function;
}
aber der 2. wird nicht akzeptiert.
Antworten:
Der globale Typ Function
dient diesem Zweck.
Wenn Sie diesen Rückruf mit 0 Argumenten aufrufen möchten und seinen Rückgabewert ignorieren, () => void
stimmt der Typ außerdem mit allen Funktionen überein, die keine Argumente annehmen.
Function
wie in der ersten Zeile dieser Antwort gezeigt, und dass der zweite Absatz (mit dem Typ () => void
oder was auch immer zum Anwendungsfall passt) bevorzugt wird?
Typescript aus Version 1.4 hat das type
Schlüsselwort, das einen Typalias deklariert (analog zu a typedef
in C / C ++). Sie können Ihren Rückruftyp folgendermaßen deklarieren:
type CallbackFunction = () => void;
Dies deklariert eine Funktion, die keine Argumente akzeptiert und nichts zurückgibt. Eine Funktion, die null oder mehr Argumente eines beliebigen Typs akzeptiert und nichts zurückgibt, wäre:
type CallbackFunctionVariadic = (...args: any[]) => void;
Dann können Sie zum Beispiel sagen:
let callback: CallbackFunctionVariadic = function(...args: any[]) {
// do some stuff
};
Wenn Sie eine Funktion wünschen, die eine beliebige Anzahl von Argumenten akzeptiert und alles zurückgibt (einschließlich void):
type CallbackFunctionVariadicAnyReturn = (...args: any[]) => any;
Sie können einige obligatorische Argumente und dann eine Reihe zusätzlicher Argumente (z. B. eine Zeichenfolge, eine Zahl und dann eine Reihe zusätzlicher Argumente) wie folgt angeben:
type CallbackFunctionSomeVariadic =
(arg1: string, arg2: number, ...args: any[]) => void;
Dies kann beispielsweise für EventEmitter-Handler hilfreich sein.
Funktionen können auf diese Weise so stark eingegeben werden, wie Sie möchten. Sie können jedoch mitgerissen werden und auf kombinatorische Probleme stoßen, wenn Sie versuchen, alles mit einem Typ-Alias festzunageln.
Function
und (...args: any[]) => any
was wird bevorzugt?
...args: any[]
ist nicht sehr nützlich.
type CallbackFunctionSomeVariadic = (arg1: string, arg2: number, ...args: any[]) => void;
was ich gesucht habe, ty.
Hier ist ein Beispiel für eine Funktion, die einen Rückruf akzeptiert
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
});
Wenn Sie sich nicht für die Rückgabewerte von Rückrufen interessieren (die meisten Leute wissen nicht, wie sie effektiv eingesetzt werden sollen), können Sie sie verwenden 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
});
Beachten Sie, dass die Signatur, die ich für den callback
Parameter verwendet habe ...
const sqk = (x: number, callback: ((_: number) => number)): number
Ich würde sagen, dass dies ein TypeScript-Mangel ist, da erwartet wird, dass wir einen Namen für die Rückrufparameter angeben. In diesem Fall habe ich verwendet, _
weil es innerhalb der sqk
Funktion nicht verwendbar ist .
Wenn Sie dies jedoch tun
// danger!! don't do this
const sqk = (x: number, callback: ((number) => number)): number
Es ist gültiges TypeScript, wird aber interpretiert als ...
// watch out! typescript will think it means ...
const sqk = (x: number, callback: ((number: any) => number)): number
Dh, wird denken , Typoskript der Parametername ist number
und die implizite Typ ist any
. Dies ist offensichtlich nicht das, was wir beabsichtigt haben, aber leider funktioniert TypeScript so.
Vergessen Sie also nicht, die Parameternamen anzugeben, wenn Sie Ihre Funktionsparameter eingeben ... so dumm es auch scheinen mag.
Sie können einen Funktionstyp in der Schnittstelle auf verschiedene Arten definieren:
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;
}
Die Verwendung ist sehr einfach,
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;
}
Es gibt vier abstrakte Funktionstypen. Sie können diese separat verwenden, wenn Sie wissen, dass Ihre Funktion Argumente akzeptiert oder nicht, Daten zurückgibt oder nicht.
export declare type fEmptyVoid = () => void;
export declare type fEmptyReturn = () => any;
export declare type fArgVoid = (...args: any[]) => void;
export declare type fArgReturn = (...args: any[]) => any;
so was:
public isValid: fEmptyReturn = (): boolean => true;
public setStatus: fArgVoid = (status: boolean): void => this.status = status;
Um nur einen Typ als Funktionstyp zu verwenden, können wir alle abstrakten Typen wie folgt miteinander kombinieren:
export declare type fFunction = fEmptyVoid | fEmptyReturn | fArgVoid | fArgReturn;
dann benutze es wie:
public isValid: fFunction = (): boolean => true;
public setStatus: fFunction = (status: boolean): void => this.status = status;
Im obigen Beispiel ist alles korrekt. Das unten stehende Verwendungsbeispiel ist jedoch aus Sicht der meisten Code-Editoren nicht korrekt.
// 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();
}
Der richtige Aufruf für Redakteure lautet wie folgt:
public callArgument(callback: fFunction) {
// pay attention in this part, for fix editor(s) error
(callback as fFunction)();
}
Typoskript: Wie definiere ich den Typ für einen Funktionsrückruf, der in einem Methodenparameter verwendet wird?
Sie können den Rückruf als 1) Funktionseigenschaft oder 2) Methode deklarieren :
interface ParamFnProp {
callback: (a: Animal) => void; // function property
}
interface ParamMethod {
callback(a: Animal): void; // method
}
Seit TS 2.6 gibt es einen wichtigen Tippunterschied :
Sie erhalten stärkere ("Sound") Typen im --strict
oder --strictFunctionTypes
Modus, wenn eine Funktionseigenschaft deklariert wird. Nehmen wir ein Beispiel:
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 gesehen sind Methoden bivariant und Funktionseigenschaften in ihren Argumenten unter kontravariantstrictFunctionTypes
. Methoden werden immer noch freizügiger überprüft (auch wenn sie nicht klingen), um in Kombination mit eingebauten Typen wie etwas praktischer zu sein Array
.