Website-Suche

Typen - Warum beschwert sich TypeScript über die Länge des Arrays?


Ich habe eine Methode, die 2 bis 4 Argumente akzeptiert:

myMethod(a: string, b: string, c?: any, d?: number);

In einem Unit-Test versuche ich, Argumente auf diese Weise an die Methode zu übergeben:

const args: [string, string, any, number] = ['a', 'b', 'c', 0];
myMethod(...args);

Obwohl ich args als eine feste Länge deklariert habe, zeigt der TypeScript-Compiler diesen Fehler:

TS2556: Erwartet 2-4 Argumente, aber 0 oder mehr erhalten.

Warum wird dieser Fehler angezeigt? Kann ich irgendetwas tun, um die letzte Zeile (den Funktionsaufruf) so zu belassen, wie sie ist?

Antwort #1

Beachten Sie, dass dieses Problem in TS3.0+ nicht mehr auftritt, siehe Playground-Link. Vorherige Antwort:


Dies ist ein bekanntes Problem, und die kurze Antwort darauf, warum es passiert, ist, dass die Unterstützung von Rest/Spread in TypeScript ursprünglich für Arrays und nicht für Tupel konzipiert wurde.

Sie können warten, bis Tupel in Rest-/Spread-Positionen in TypeScript unterstützt werden; es soll angeblich ab TypeScript 3.0 eingeführt werden, das bald erscheinen sollte.

Bis dahin sind Ihre einzigen Optionen Umgehungslösungen. Sie könnten die Spread-Syntax aufgeben und die Argumente einzeln übergeben:

myMethod(args[0], args[1], args[2], args[3]);  // type safe but not generalizable

oder behaupten, dass Ihre Methode ...args: any[] akzeptiert, wie in:

(myMethod as (...args:any[])=>void)(...args);  // no error, not type safe

oder den Fehler ignorieren,

// @ts-ignore
myMethod(...args); // no error, not type safe

BEARBEITEN: oder verwenden Sie die derzeit nicht gut getypte apply()-Methode (die im Gegensatz zu den vorherigen beiden Workarounds das ausgegebene JS ändert):

myMethod.apply(this, args); // no error, not type safe

Keines davon ist großartig, also wenn es eine Option ist, auf die Implementierung der Funktion zu warten, könnten Sie das in Erwägung ziehen. Viel Glück!