TypeScript, привязка нескольких параметров к одному типу
есть ли способ достичь следующего с помощью TypeScript?
function add(x, y) {
return x + y;
}
Я хочу, чтобы скомпилировать следующее:
add(1, 2);
add("hello ", "world");
но я не хочу компилировать следующее:
add(4, "world");
add("hello ", 4);
обратите внимание также, я хочу, чтобы он компилировался только для строк и чисел.
2 ответов
вы можете сделать это с помощью общих типов:
function add<T extends string | number>(x: T, y: T): T {
return x + y;
}
add<string>("a", "b"); // OK
add<number>(5, 3); // OK
add<boolean>(true, false); // Type 'boolean' does not satisfy constraint 'string | number'
обратите внимание, что вам не всегда нужно давать общий тип при вызове функции, если он удовлетворяет ограничениям:
add("a", "b"); // OK
add(5, 3); // OK
add(5, "b"); // Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'.
add(true, "c"); // Type argument candidate 'boolean' is not a valid type argument because it is not a supertype of candidate 'string'.
как вы можете видеть, это сказать:
-
x
иy
должен быть того же типа - этот тип должен быть
string
илиnumber
(либо продление либо)
компилятор TypeScript умный достаточно разработать тип без указания дженериков в вызовах (но вы должны поместить их в определение).
как вы заметили, это проблема с компилятор TypeScript. Я зарегистрировал его на машинописном GitHub РЕПО.
на данный момент, Вы можете сделать это:
function add<T extends string | number>(x: T, y: T): T {
return <any>x + <any>y;
}
x
и y
по-прежнему типа T
(обеспечивается компилятором), но мы обманываем его, позволяя нам делать +
на них.
Это можно сделать так:
function add<T extends string | number>(x: T, y: T): T;
function add(x: any, y: any) {
return x + y;
}
let s = add("a", "b"); // fine
let n = add(1, 2); // fine
let n2 = add(1,"2"); // error
вот как вы должны это сделать сейчас, хотя я рад, что @JamesMongar открыл проблему GitHub. Если T расширяет строку или число примитивов, то оператор + на T обязательно должен быть законным.