Соответствующая проблема в GitHub: Microsoft / TypeScript # 12410 .Ваш конкретный вопрос рассматривается в комментарии Райан Кавано :
T + T
, где T
расширяется string | number
все еще не разрешено - мыне думаю, что это хороший вариант использования, потому что, если вы получаете конкатенацию или сложение, не предсказуемо, то есть то, что людям не следует делать.
То же самое происходит с вами, если вы просто попытаетесьсложить два string | number
типа вместе:
declare const x: string | number;
x + x; // error!
// Operator '+' cannot be applied to types 'string | number' and 'string | number'.
Так что я думаю, они серьезно, что они не хотят, чтобы вы это делали.Вы всегда можете согнуть компилятор по своему желанию и отключить проверку типа с помощью подтверждения типа ;
export const addNumbersOrCombineStrings = <T extends string | number>(
param1: T,
param2: T
): T => (param1 as any) + param2;
Но вы не хотите этого делать, тем более что T extends string | number
будет вывод a строка или число литерал, который не дает ожидаемого поведения:
const notThree = addNumbersOrCombineStrings(1, 2);
// const notThree: 1 | 2
const notHi = addNumbersOrCombineStrings("h", "i");
// const notHi: "h" | "i"
Ой, эти результаты являются объединениямилитералов.И чтобы исправить это, используя дженерики, вы, вероятно, захотите начать использовать необычные условные типы для расширения литералов:
type SN<T extends string | number> = (T extends string ? string : never) |
(T extends number ? number : never);
export const addNumbersOrCombineStrings = <T extends string | number>(
param1: T,
param2: SN<T>
): SN<T> =>
(param1 as any) + param2;
const n = addNumbersOrCombineStrings(1, 2); // const n : number;
const s = addNumbersOrCombineStrings("h","i"); // const s: string;
// and do you even want to support this:
const sn = addNumbersOrCombineStrings(
Math.random() < 0.5 ? "a" : 1,
Math.random() < 0.5 ? "b" : 2
); // const sn: string | number;
Но, возможно, есть и крайние случаи (например, когдапереданное значение на самом деле string | number
, как в случае sn
выше).Я начинаю понимать, почему они не хотят добавлять значения типа string | number
вместе.Во всяком случае, надеюсь, что это помогает.Удачи!