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

使用模板字面量为TypeScript对象添加键时遇类型错误求助

解决TypeScript中模板字面量索引泛型对象的类型错误

你遇到的错误是因为TypeScript无法推断模板字面量生成的键属于泛型对象的合法索引,且泛型Datum默认被视为unknown类型,导致索引操作不安全。

问题代码及错误

错误信息:

Element implicitly has an 'any' type because expression of type '${string}Bar' can't be used to index type 'unknown'.

原代码:

type FooDatum = {
  foo: string;
  baz: string;
  fooBar?: string;
}

function addFooBar<Datum>(obj: Datum, dataKey: keyof Datum) {
  obj[`${String(dataKey)}Bar`] = obj[dataKey];

  return obj;
}

addFooBar<FooDatum>({ foo: 'bar', baz: 'string' }, 'foo')

解决方案

通过约束泛型范围、捕获具体键类型并明确返回类型,让TypeScript识别模板字面量生成的键是合法索引:

type FooDatum = {
  foo: string;
  baz: string;
  fooBar?: string;
}

// 约束Datum为对象类型,K为Datum的具体键
function addFooBar<Datum extends object, K extends keyof Datum>(
  obj: Datum, 
  dataKey: K
): Datum & { [P in `${K}Bar`]: Datum[K] } {
  // 断言新键的类型为模板字面量类型
  const newKey = `${dataKey}Bar` as `${K}Bar`;
  // 赋值时确保类型匹配
  obj[newKey] = obj[dataKey] as Datum[K];
  // 断言返回类型为原对象加新键的交叉类型
  return obj as Datum & { [P in `${K}Bar`]: Datum[K] };
}

const result = addFooBar({ foo: 'bar', baz: 'string' }, 'foo');
// 此时result.fooBar类型为string,类型检查通过

关键说明

  1. 泛型约束:Datum extends object确保传入的参数是对象,避免unknown类型导致的索引错误。
  2. 具体键捕获:K extends keyof Datum让TypeScript记住传入的具体键名,从而生成准确的模板字面量类型(比如传入'foo'时,生成'fooBar')。
  3. 返回类型定义:Datum & { [P in ${K}Bar]: Datum[K] }明确返回的对象包含原属性和新生成的键,类型与原键值类型一致,保证类型安全。
  4. 类型断言:通过as ${K}Bar``和返回值的断言,让TypeScript认可模板字面量键的合法性,避免类型报错。

内容的提问来源于stack exchange,提问作者Spencer Carney

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:52:39