You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript泛型算术报错:运算符'+'无法应用于Summable类型

为什么TypeScript中联合类型string | number无法直接使用+运算符?

问题代码

type Summable = string | number;

interface Calculation<Type> {
  number1: Type;
  number2: Type;
  operation(): Type;
}

class Addition<Summable> implements Calculation<Summable> {
  number1: Summable;
  number2: Summable;

  constructor(number1: Summable, number2: Summable) {
    this.number1 = number1;
    this.number2 = number2;
  }

  operation(): Summable {
    console.log(`Calculating Addition .... between ${this.number1} and ${this.number2}`);

    let val: Summable = this.number1 + this.number2;

    return val;
  }
}

function main() {
  let adder: Addition<number> = new Addition<number>(2, 3);
  console.log(adder.operation());
}

main();

报错信息

Operator '+' cannot be applied to types 'Summable' and 'Summable'.ts(2365)

原因分析

你遇到的问题主要有两个核心点:

  1. 泛型参数命名冲突
    你在class Addition<Summable>中把Summable用作了泛型参数名,这直接覆盖了外部定义的type Summable = string | number类型别名。此时类内部的Summable是一个未受约束的泛型类型,TypeScript无法确定它支持+运算符,自然会报错。

  2. 联合类型的类型安全限制
    就算你修正了命名冲突,直接对string | number联合类型使用+运算符仍然会报错。这是因为TypeScript的类型系统要保证操作的确定性:联合类型允许number和string的混合(比如一个参数是number,另一个是string),而JavaScript中1 + '2'会得到字符串'12',这可能和你预期的数值加法不符。为了避免这种非预期行为,TypeScript会禁止对不确定类型的联合类型直接执行+运算。

解决方案

修正泛型命名冲突,并通过类型守卫确保运算的类型一致性:

type Summable = string | number;

interface Calculation<Type> {
  number1: Type;
  number2: Type;
  operation(): Type;
}

// 将泛型参数改为T,并约束为Summable的子类型,避免命名冲突
class Addition<T extends Summable> implements Calculation<T> {
  number1: T;
  number2: T;

  constructor(number1: T, number2: T) {
    this.number1 = number1;
    this.number2 = number2;
  }

  operation(): T {
    console.log(`Calculating Addition .... between ${this.number1} and ${this.number2}`);

    // 用typeof类型守卫判断具体类型,确保运算合法
    if (typeof this.number1 === 'number' && typeof this.number2 === 'number') {
      return (this.number1 + this.number2) as T;
    } else if (typeof this.number1 === 'string' && typeof this.number2 === 'string') {
      return (this.number1 + this.number2) as T;
    }

    // 兜底错误,实际不会触发(构造函数已约束参数类型为T)
    throw new Error('Only number or string types are supported for addition');
  }
}

function main() {
  const numberAdder = new Addition<number>(2, 3);
  console.log(numberAdder.operation()); // 输出5

  const stringAdder = new Addition<string>('Hello ', 'World');
  console.log(stringAdder.operation()); // 输出Hello World
}

main();

说明

  • 泛型约束T extends Summable确保了T只能是number或string,同时避免了和外部类型别名的命名冲突。
  • 类型守卫typeof让TypeScript在编译期就能确定当前操作数的具体类型,从而允许合法的+运算。

内容的提问来源于stack exchange,提问作者Kevin Martin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 08:07:40