Firmas de tipo TypeScript para funciones con recuentos de argumentos variables


107

Tengo problemas para definir interfaces con miembros de funciones que aceptan cantidades variables de argumentos. Tome el siguiente objeto literal como ejemplo:

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

Me gustaría poder definir una interfaz como:

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

Para que el siguiente código pueda compilarse sin error:

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

Respuestas:


205

TypeScript utiliza la propuesta de extensión ECMAScript 6,

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

pero agrega anotaciones de tipo para que se vea así,

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

Perfecto: por alguna razón, no pude encontrar nada sobre esto en el documento de especificaciones de idioma, pero parece funcionar bien. Gracias.
— nxn

4
@nxn Página 50/51 en las especificaciones: RestParameter
— AM

@PulsarBlow Ah, no estaba familiarizado con que se llamaran Parámetros de descanso. Gracias por informarme dónde encontrarlos en la especificación.
— nxn

7
@JanusTroelsen Me doy cuenta de que llego muy tarde, pero para cualquiera que se encuentre con esta publicación, asegúrese de no olvidar marcar RestParameter como una matriz. ...args:any[]es correcto pero ...args:anyno lo es.
— GuiSim

1
@AlexanderMills func es el nombre de la función.
— Bob Vale

5

Solo para agregar a la respuesta de Chuck, no necesita tener una interfaz definida como tal. Puedes hacerlo ...directamente en el método:

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

Entonces puedes llamarlo:

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

O

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

0

Si no se usa el argumento ... args [], Typescript aún crea una matriz en Javascript y copia los argumentos en ella.

Para evitar esta innecesaria, puede hacer un prototipo para la función así como la función, así: -

function format_n(str: string, ... $n: any[]): string;
function format_n(str: string): string {
    return str.replace(/%(\d+)/g, (_, n) => format_n.arguments[n]);
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.