运算符“+”不能应用于类型“T”和“T”。在打字稿中

Hes*_*hal 2 generics types typescript

我对 TypeScript 很陌生。我的 TypeScript 版本是 3.7.5。

恕我直言,这应该很容易,但我不知道为什么它不起作用。

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

console.log(add (5, 6));
Run Code Online (Sandbox Code Playgroud)

我收到错误:

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

我也用过这个:

function add<T extends string | number > (a:T, b:T):T
Run Code Online (Sandbox Code Playgroud)

有同样的错误。如果我不能使用+这个泛型,我为什么要使用泛型

bel*_*a53 10

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

function add<T extends string | number > (a:T, b:T):T也不会起作用,因为 TypeScript 需要至少一个操作数为string,而此处并非如此。例如,这个星座怎么样:

const sn1 = 3 as number | string
const sn2 = "dslf" as number | string
add(sn1, sn2) // Both types have type number | string, sh*t...
Run Code Online (Sandbox Code Playgroud)

+运营商不能超载,但我们仍然可以利用函数重载在打字稿:

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
Run Code Online (Sandbox Code Playgroud)


Med*_*uly 6

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

联合加法

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'.
Run Code Online (Sandbox Code Playgroud)

操场



TypeScript 函数重载

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.
Run Code Online (Sandbox Code Playgroud)

操场

  • 这个答案目前正在[元](https://meta.stackoverflow.com/questions/403191)上讨论。 (22认同)

Ste*_*pUp 4

看起来有必要设置这样的约束:

add<T extends number> (a:T, b:T):number {
    return a + b;
}
Run Code Online (Sandbox Code Playgroud)

或:Tstring

add<T extends string> (a:T, b:T):string {
    return a + b;
}
Run Code Online (Sandbox Code Playgroud)

此版本不符合条件,因为无法预测您是否会进行串联或添加。

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

}
Run Code Online (Sandbox Code Playgroud)

  • 更通用的方法可能是创建一个带有“add: (other: T) =&gt; T;”成员的接口并将其用作约束。如果我们可以重载运算符就好了! (2认同)