使用模板字面量为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,类型检查通过
关键说明
- 泛型约束:
Datum extends object确保传入的参数是对象,避免unknown类型导致的索引错误。 - 具体键捕获:
K extends keyof Datum让TypeScript记住传入的具体键名,从而生成准确的模板字面量类型(比如传入'foo'时,生成'fooBar')。 - 返回类型定义:
Datum & { [P in${K}Bar]: Datum[K] }明确返回的对象包含原属性和新生成的键,类型与原键值类型一致,保证类型安全。 - 类型断言:通过
as${K}Bar``和返回值的断言,让TypeScript认可模板字面量键的合法性,避免类型报错。
内容的提问来源于stack exchange,提问作者Spencer Carney
相关产品推荐
相关产品推荐

