Typescript 操作员'+';无法应用于类型';T';和';T';。打字

Typescript 操作员'+';无法应用于类型';T';和';T';。打字,typescript,generics,types,Typescript,Generics,Types,我对打字很不熟悉。我的打字脚本版本是3.7.5 嗯,这应该很容易,但我不知道为什么它不起作用 function add<T> (a:T, b:T):T { return a + b ; } console.log(add (5, 6)); 函数添加(a:T,b:T):T{ 返回a+b; } 控制台日志(添加(5,6)); 我得到一个错误: 运算符“+”不能应用于类型“T”和“T” 我也用过这个: function add<T extends string | n

我对打字很不熟悉。我的打字脚本版本是3.7.5

嗯,这应该很容易,但我不知道为什么它不起作用

function add<T> (a:T, b:T):T  {
    return a + b ;
}

console.log(add (5, 6));
函数添加(a:T,b:T):T{
返回a+b;
}
控制台日志(添加(5,6));
我得到一个错误:

运算符“+”不能应用于类型“T”和“T”

我也用过这个:

function add<T extends string | number > (a:T, b:T):T
函数添加(a:T,b:T):T

同样的错误也存在。如果我不能对此泛型使用
+
,为什么要使用泛型?

看起来有必要设置如下约束:

add<T extends number> (a:T, b:T):number {
    return a + b;
}
此版本不合格,因为无法预测您是获得连接还是添加

add<T extends string | number > (a:T, b:T):T {

}
add(a:T,b:T):T{
}

泛型在这里不是正确的方法。您不能将
+
运算符应用于无约束的
T
(为什么要这样做?)

函数add(a:T,b:T):T
也不起作用,因为TypeScript要求至少有一个操作数是
字符串,这里不是这样。例如,这个星座呢:

const sn1 = 3 as number | string
const sn2 = "dslf" as number | string
add(sn1, sn2) // Both types have type number | string, sh*t...
+
运算符不能重载,但我们仍然可以在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

这些是非常常见的解决方案:

联合加法

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'.

函数addString(x:T,y:T):字符串{
返回x+y;
}
函数addNum(x:T,y:T):编号{
设a=x*y;
设b=x-y;
设z=x++;
返回x+y;
}
添加字符串(“a”、“b”);
addNum(1,2);

更通用的方法可能是创建一个带有
add:(other:T)=>T成员并将其用作约束。如果我们能让操作员超负荷工作,那就太好了!!如果我同时定义这两个函数,我会得到这样的结果:重复函数实现。如果我只想定义一个,为什么我要选择T,我可以简单地用number``函数add(a:number,b:number):number{returna+b;}console.log(add(5,6))```@HesamA是的,你是对的,你可以简单地定义为
add(a:number,b:number):number{returna+b;}
“这个版本不合格,因为你得到的是串联还是相加都是不可预测的。”这有关系吗?我很感兴趣的是为什么这个版本不起作用,约束似乎满足了,如果签名满足了,那么它的concat或addition是一个实现细节,与T扩展IHasAdd和非运算符add操作相同,用于数字加法和字符串concat。@M–ttFrëman
T扩展字符串| number然后T可以是字符串| number
表示一个
T
类型的值可以是字符串,另一个
T
类型的值可以是
数字
。问题问题不是为什么不能将+用于泛型,而是为什么要对数字以外的任何对象执行算术?@AliHabibzadeh算术或字符串串联。您可以很容易地进行类似于
[“a”、“b”、“c”]的操作。reduce(add)
一次获取两个字符串并通过二进制函数传递。您不需要添加或减去字符串。您需要使用字符串插值、.concat等。。数学运算不适用于字符串。如果您将它们用于字符串,那么您的编码是错误的。为什么您认为JS允许重载?我的意思是,要更新。
为什么应该这样做?
-您能解释一下为什么不应该这样做吗?@SET编译器对
t
一无所知,在这种情况下,
unknown
作为上限类型。所以从TS的角度来看,这可能是一个错误。如果他们使用ES6呢?箭头功能?确实,为什么不使用
any
解决任何与TS相关的问题?此答案目前正在讨论中。感谢您的贡献。考虑向代码添加解释,因为这样会更有帮助。您可以(无需“编辑:”、“更新:”,或类似内容-答案应显示为今天编写的)。
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'.
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.
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);