Сигнатуры типа TypeScript для функций с переменным количеством аргументов


109

У меня проблемы с определением интерфейсов с функциями-членами, которые принимают переменное количество аргументов. В качестве примера возьмем следующий литерал объекта:

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

Я хотел бы иметь возможность определять такой интерфейс, как:

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

Чтобы следующий код можно было скомпилировать без ошибок:

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

Ответы:


206

TypeScript использует предложение распространения ECMAScript 6,

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

но добавляет аннотации типов, чтобы это выглядело так,

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

Идеально - по какой-то причине я не смог найти ничего об этом в спецификации языка, но, похоже, все работает нормально. Спасибо.
— nxn

4
@nxn Страница 50/51 в спецификациях: RestParameter
— AM

@PulsarBlow А, я не знал, что они называются параметрами отдыха. Спасибо, что сообщили мне, где их найти в спецификации.
— nxn

7
@JanusTroelsen Я понимаю, что очень опаздываю, но всем, кто наткнется на этот пост, убедитесь, что вы не забыли пометить RestParameter как массив. ...args:any[]правильно, но ...args:anyэто не так.
— GuiSim 02

1
@AlexanderMills func - это имя функции.
— Bob Vale

5

Просто чтобы добавить к ответу Чака, вам не нужно определять интерфейс как таковой. Вы можете просто сделать это ...прямо в методе:

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

Тогда вы можете назвать это:

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

Или

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

0

Если аргумент ... args [] не используется, Typescript по-прежнему создает массив в Javascript и копирует в него аргументы.

Чтобы избежать этой ненужности, вы можете создать прототип функции, а также функции, таким образом: -

function format_n(str: string, ... $n: any[]): string;
function format_n(str: string): string {
    return str.replace(/%(\d+)/g, (_, n) => format_n.arguments[n]);
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.