Operator '+' cannot be applied to types 'T' and 'T'. in TypeScript

前提是你 提交于 2021-01-01 02:41:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!