TypeScript-Typensignaturen für Funktionen mit variablen Argumenten


107

Ich habe Probleme beim Definieren von Schnittstellen mit Funktionselementen, die unterschiedlich viele Argumente akzeptieren. Nehmen Sie als Beispiel das folgende Objektliteral:

var obj = {
    func: () => {
        for(var i = 0; i < arguments.length; i++) {
            console.log(arguments[i]);
        }
    }
};

Ich möchte in der Lage sein, eine Schnittstelle zu definieren wie:

interface IExample {
    func: ( ??? ) => void;
}

Damit der folgende Code fehlerfrei kompiliert werden kann:

var test = (o: IExample) {
    o.func("a");
    o.func("a", "b");
    o.func("a", "b", "c");
    ...
}

Antworten:


204

TypeScript verwendet den ECMAScript 6-Verbreitungsvorschlag.

http://wiki.ecmascript.org/doku.php?id=harmony:spread

Fügt aber Typanmerkungen hinzu, damit dies so aussieht:

interface Example {
    func(...args: any[]): void;
}

Perfekt - aus irgendeinem Grund konnte ich im Sprachspezifikationsdokument nichts darüber finden, aber es scheint gut zu funktionieren. Danke dir.
— nxn

3
@nxn Seite 50/51 in den Spezifikationen: RestParameter
— AM

@PulsarBlow Ah, ich war nicht damit vertraut, dass sie Restparameter genannt werden. Vielen Dank, dass Sie mich wissen lassen, wo sie in der Spezifikation zu finden sind.
— Nxn

7
@JanusTroelsen Mir ist klar, dass ich sehr spät bin, aber für alle, die über diesen Beitrag stolpern, sollten Sie nicht vergessen, den RestParameter als Array zu markieren. ...args:any[]ist richtig, aber ...args:anynicht.
— GuiSim

1
@AlexanderMills func ist der Name der Funktion.
— Bob Vale

5

Um die Antwort von Chuck zu ergänzen, muss keine Schnittstelle als solche definiert sein. Sie können dies einfach ...direkt in der Methode tun :

class Header { constructor(public name: string, public value: string) {} }

getHeaders(...additionalHeaders: Header[]): HttpHeaders {
    let headers = new HttpHeaders();
    headers.append('Content-Type', 'application/json')

    if (additionalHeaders && additionalHeaders.length)
        for (var header of additionalHeaders)
            headers.append(header.name, header.value);

    return headers;
}

Dann können Sie es nennen:

headers: this.getHeaders(new Header('X-Auth-Token', this.getToken()))

Oder

headers: this.getHeaders(new Header('X-Auth-Token', this.getToken()), new Header('Something', "Else"))

0

Wenn das Argument ... args [] nicht verwendet wird, erstellt Typescript weiterhin ein Array im Javascript und kopiert die Argumente in dieses.

Um diese Unnötigkeit zu vermeiden, können Sie einen Prototyp sowohl für die Funktion als auch für die Funktion erstellen.

function format_n(str: string, ... $n: any[]): string;
function format_n(str: string): string {
    return str.replace(/%(\d+)/g, (_, n) => format_n.arguments[n]);
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.