问题
I am very new to TypeScript. My TypeScript version is 3.7.5.
IMHO, it should be very easy, but I don't know why it does not work.
function add<T> (a:T, b:T):T {
return a + b ;
}
console.log(add (5, 6));
I get the error:
Operator '+' cannot be applied to types 'T' and 'T'.
I used this one also:
function add<T extends string | number > (a:T, b:T):T
The same error is there. If I can not use +
for this generic, why should I use generics?
回答1:
Generics are not the right approach here. You cannot apply the +
operator to an unconstrained T
(why should this work?).
function add<T extends string | number > (a:T, b:T):T
won't work either, because TypeScript requires at least one operand to be string
, which is not the case here. E.g., what about this constellation:
const sn1 = 3 as number | string
const sn2 = "dslf" as number | string
add(sn1, sn2) // Both types have type number | string, sh*t...
The +
operator cannot be overloaded, but we can still leverage function overloads in TypeScript:
function add(a: string, b: string): string
function add(a: number, b: number): number
function add(a: any, b: any) {
return a + b;
}
add(1, 2) // Number
add("foo", "bar") // String
回答2:
These are quite common solutions:
Union addition
function add<T extends string | number>(a: T, b: T): T extends string ? string : number {
return <any>a + <any>b; // Cast to any as unions cannot be added, still have proper typings applied
}
const res1 = add(5, 6) // number
const res2 = add('a', 'b') // string
const res3 = add(5, 'b') // Argument of type '"b"' is not assignable to parameter of type '5'.
Playground
TypeScript function overloading
function add(a: string, b: string): string
function add(a: number, b: number): number
function add(a: any, b: any): string | number {
return a + b;
}
const res1 = add(1, 2); // Number
const res2 = add('a', 'b'); // String
const res3 = add(1, 'b'); // Overload 1 of 2, '(a: string, b: string): string', gave the following error.
Playground
回答3:
It looks like it is necessary to set constraints like this:
add<T extends number> (a:T, b:T):number {
return a + b;
}
or T
of string
:
add<T extends string> (a:T, b:T):string {
return a + b;
}
This version is not eligible, as whether you get concatenation or addition is not predictable.
add<T extends string | number > (a:T, b:T):T {
}
回答4:
function addString<T extends string>(x: T, y: T): string {
return x + y;
}
function addNum<T extends number>(x: T, y: T): number {
let a = x * y;
let b = x - y;
let z = x++;
return x + y;
}
addString("a", "b");
addNum(1, 2);
来源:https://stackoverflow.com/questions/59802954/operator-cannot-be-applied-to-types-t-and-t-in-typescript