Podpisy typu TypeScript dla funkcji ze zmienną liczbą argumentów


108

Mam problem ze zdefiniowaniem interfejsów z elementami członkowskimi funkcji, które akceptują zmienne ilości argumentów. Jako przykład weźmy następujący literał obiektu:

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

Chciałbym móc zdefiniować interfejs, taki jak:

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

Aby następujący kod mógł się skompilować bez błędów:

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

Odpowiedzi:


205

TypeScript korzysta z propozycji rozkładów ECMAScript 6,

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

ale dodaje adnotacje typu, tak by to wyglądało,

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

Idealnie - z jakiegoś powodu nie mogłem znaleźć nic na ten temat w dokumencie specyfikacji języka, ale wydaje się, że działa dobrze. Dziękuję Ci.
— nxn

4
@nxn Strona 50/51 w specyfikacji: RestParameter
— AM

@PulsarBlow Ach, nie znałem ich nazywania parametrami odpoczynku. Dziękuję za poinformowanie mnie, gdzie je znaleźć w specyfikacji.
— nxn

7
@JanusTroelsen Zdaję sobie sprawę, że jestem bardzo spóźniony, ale dla każdego, kto natknie się na ten post, upewnij się, że nie zapomnisz oznaczyć RestParameter jako tablicy. ...args:any[]jest poprawne, ale ...args:anynie jest.
— GuiSim

1
@AlexanderMills func to nazwa funkcji.
— Bob Vale,

5

Aby dodać do odpowiedzi Chucka, nie musisz mieć zdefiniowanego jako takiego interfejsu. Możesz po prostu zrobić ...bezpośrednio w metodzie:

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

Wtedy możesz to nazwać:

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

Lub

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

0

Jeśli argument ... args [] nie jest używany, Typescript nadal tworzy tablicę w JavaScript i kopiuje do niej argumenty.

Aby uniknąć tej niepotrzebności, możesz wykonać prototyp zarówno funkcji, jak i funkcji, w ten sposób: -

function format_n(str: string, ... $n: any[]): string;
function format_n(str: string): string {
    return str.replace(/%(\d+)/g, (_, n) => format_n.arguments[n]);
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.