如何在TypeScript中使用转换映射重命名对象属性?
实现属性重命名并保留类型的TypeScript函数
要实现你需要的功能,核心是利用TypeScript 4.1+支持的键重映射特性,直接在返回类型中完成原属性到新属性的类型映射,同时严格限制返回对象的键集合。
完整函数实现
export function renameProperties< TInput extends Record<string, unknown>, TConversionMap extends Record<keyof TInput, string> >(input: TInput, conversionMap: TConversionMap): { // 遍历原输入的每个键,用转换映射替换键名,保留原属性类型 [K in keyof TInput as TConversionMap[K]]: TInput[K] } { // 执行实际的属性重命名逻辑 const result: Record<string, unknown> = {}; for (const key in input) { if (Object.prototype.hasOwnProperty.call(input, key)) { const newKey = conversionMap[key]; result[newKey] = input[key]; } } return result as { [K in keyof TInput as TConversionMap[K]]: TInput[K] }; }
关键逻辑说明
泛型约束:
TInput约束为任意字符串键的对象,确保输入是可遍历的键值对。TConversionMap约束为必须包含TInput所有键的对象,且值为字符串(新属性名),避免遗漏或错误的转换映射。
返回类型映射:
[K in keyof TInput as TConversionMap[K]]:遍历原输入的每个键K,通过as将键重命名为conversionMap[K]对应的新名称。: TInput[K]:新属性的类型完全继承原输入中K键的类型,完美保留类型信息。
验证示例
const input = {a: 1, b: "hello"}; const result = renameProperties(input, {a: "alpha", b: "beta"}); result.alpha; // 类型自动推断为number result.beta; // 类型自动推断为string result.foo; // 直接报错:类型“{ alpha: number; beta: string; }”上不存在属性“foo”
你之前尝试的问题分析
你之前写的TOutput extends {[K in TConversionMap[keyof TInput]] : string}存在两个问题:
- 类型丢失:所有属性都被强制设为
string,没有保留原输入的类型。 - 键集合不严格:
TConversionMap[keyof TInput]会生成新键的联合类型,但extends允许返回对象包含额外键(比如foo),导致访问不存在的属性不会报错。
而键重映射的方式直接生成精确的返回类型,既保留原类型,又严格限制只能存在转换后的键,完全符合你的需求。
内容的提问来源于stack exchange,提问作者dwjohnston
相关产品推荐
相关产品推荐

