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

如何在TypeScript中添加带后缀的索引签名?

问题分析与解决方案

原代码的错误点

  1. 映射类型语法错误:你写的[index: ${K in keyof T}_X]: true不符合TypeScript映射类型的规范。映射类型需要用as关键字来生成新的键名,正确的结构应该是遍历原类型的键,再通过模板字符串拼接后缀。
  2. 返回类型定义错误:convertForApi返回的是原对象加上带_X后缀的标记属性,所以返回类型不能只写ApiBoolean<T>,而是原类型T和标记属性类型的交叉类型,否则原对象的属性会被类型检查判定为不存在。
  3. 类型赋值不兼容:直接把{...obj}赋值给ApiBoolean<T>类型的变量,TypeScript会报错,因为原对象的属性不在ApiBoolean<T>的定义里,需要合理的类型断言来解决。

修正后的实现代码

// 正确定义带_X后缀的标记属性类型
type ApiUpdateMarkers<T extends object> = {
  [K in keyof T as `${K & string}_X`]: true;
};

// 函数返回原对象+标记属性的交叉类型
function convertForApi<T extends object>(obj: T, keys: Array<keyof T>): T & ApiUpdateMarkers<T> {
  // 使用类型断言把原对象转为交叉类型
  const returnObj = {...obj} as T & ApiUpdateMarkers<T>;
  for (const k of keys) {
    // 确保键是字符串类型,再拼接后缀
    returnObj[`${k as string}_X`] = true;
  }
  return returnObj;
}

const person = {
  firstName: 'Joe',
  lastName: 'Smith',
  age: 35
};

const converted = convertForApi(person, ['lastName', 'age']);
// converted的类型会是:{ firstName: string; lastName: string; age: number; lastName_X: true; age_X: true }

关键细节说明

  • K & string:因为keyof T可能包含symbol类型的键,用& string确保只有字符串类型的键会被拼接后缀,避免类型错误。
  • 交叉类型T & ApiUpdateMarkers<T>:让返回值同时保留原对象的所有属性和新增的标记属性,类型检查完全符合预期。
  • 类型断言:在赋值和设置属性时使用as,是因为TypeScript无法自动推断动态添加的后缀属性类型,合理的断言可以解决类型不兼容问题。

内容的提问来源于stack exchange,提问作者Chris Barr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 15:15:03