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

TypeScript对象键重映射方法的强类型定义问题

对象键重映射方法的TypeScript强类型修复

我需要给一个按映射表重映射对象键的方法添加TypeScript强类型,期望调用remapKeys({key1: "xxx", key2: "yyy"}, {key1: "newKey"})时,返回值的类型是{ newKey: string; key2: string; },但当前用联合类型组合未映射属性和重映射类型的写法,返回值的隐式类型被放宽为键类型是string的对象,达不到预期。

当前的错误类型定义代码:

type MappedKeys<T extends { [key: string]: any }, M extends { [K in keyof Partial<T>]: string }> = 
  | Omit<T, keyof M>
  | { [P in keyof T & keyof M as M[P]]: T[P] };

function remapKeys<T extends { [key: string]: any }, M extends { [K in keyof Partial<T>]: string }>(
  obj: T,
  mappings: M,
): MappedKeys<T, M>;

问题原因

用联合类型|会让TypeScript把返回值解析成两个独立对象类型的联合,而不是合并后的单一对象类型,所以最终类型被推断为宽泛的{ [key: string]: any },无法精确识别具体的键。

解决方案

把联合类型换成交叉类型&,让TypeScript将未映射的属性类型和重映射后的属性类型合并成一个完整的对象类型。同时优化类型约束,让定义更规范严谨:

// 修正后的类型定义:用交叉类型合并两种属性
type MappedKeys<T extends Record<string, any>, M extends Record<keyof T, string>> = 
  Omit<T, keyof M> & { [P in keyof T & keyof M as M[P]]: T[P] };

// 带实现的方法
function remapKeys<T extends Record<string, any>, M extends Record<keyof T, string>>(
  obj: T,
  mappings: M
): MappedKeys<T, M> {
  const result = { ...obj };
  for (const [oldKey, newKey] of Object.entries(mappings)) {
    if (oldKey in result) {
      result[newKey as keyof typeof result] = result[oldKey as keyof typeof result];
      delete result[oldKey as keyof typeof result];
    }
  }
  return result as MappedKeys<T, M>;
}

测试验证

const testResult = remapKeys({key1: "xxx", key2: "yyy"}, {key1: "newKey"});
// 类型推断正确:testResult的类型为 { key2: string; newKey: string; }
testResult.newKey; // 正常访问,无类型错误
testResult.key2; // 正常访问
// @ts-expect-error 原key1已被移除,TypeScript会提示错误
testResult.key1;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:15:41