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

TypeScript中为什么无法通过该方式递增对象属性?

解决方案

报错的本质是string类型的prop无法保证是Test1 | Test2 | Test3上存在的合法索引,你不想给类型加索引签名放宽属性约束的话,可以选择以下两种适配方案:

方案1:编译期静态约束(更推荐)

用泛型约束prop一定是传入对象自身的合法键,从调用阶段就杜绝非法传参,不需要额外运行时判断:

type Test1 = {
  srn1: number
}

type Test2 = {
  srn2: number
}

type Test3 = {
  srn3: number
}

const test1: Test1 = { srn1: 1 };
const test2: Test2 = { srn2: 2 };
const test3: Test3 = { srn3: 3 };

// 泛型约束:prop 一定是传入 obj 自身的键
function incrementSrn<T extends Test1 | Test2 | Test3>(prop: keyof T, obj: T): void {
  obj[prop] += 1;
}

incrementSrn('srn1', test1); // 正常编译
incrementSrn('srn2', test1); // 编译报错,提前发现参数不匹配

方案2:运行时动态校验

如果prop是运行时才能确定的动态字符串,可以自定义类型守卫收窄索引类型,不需要修改原有类型定义:

// 通用类型守卫:判断 key 是否为 obj 的合法键
function isValidKey<T extends object>(key: PropertyKey, obj: T): key is keyof T {
  return key in obj;
}

function incrementSrn(prop: string, obj: Test1 | Test2 | Test3): void {
  if (isValidKey(prop, obj)) {
    // 进入判断分支后 TS 已经确认 prop 是 obj 的合法键,不会触发索引报错
    obj[prop] += 1;
  }
}

两种方案都不会修改原有Test1/Test2/Test3的类型约束,依然不允许声明外的额外属性。

内容的提问来源于stack exchange,提问作者Александр Макаров

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 03:00:05