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


107

У мене виникають проблеми з визначенням інтерфейсів із членами функції, які приймають змінні обсяги аргументів. Візьмемо наступний буквальний об'єкт як приклад:

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");
    ...
}

Відповіді:


205

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

1
@AlexanderMills func - це назва функції.
— Боб Вейл

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.