
本文介绍如何使用 TypeScript 的键重映射(key-remapped)类型,编写一个类型安全的 mapSelf 函数,将对象的值作为新对象的键、原键作为新值,并确保类型推导精确到每个属性级。
本文介绍如何使用 typescript 的键重映射(key-remapped)类型,编写一个类型安全的 `mapself` 函数,将对象的值作为新对象的键、原键作为新值,并确保类型推导精确到每个属性级。
在 JavaScript 中,将对象键值互换是一个常见操作,例如将 { a: "aee", b: "bee" } 转为 { aee: "a", bee: "b" }。但若直接迁移到 TypeScript,仅靠 Record<t t keyof></t> 会导致类型信息丢失——如 test.aee 的类型被宽泛推导为 "a" | "b" | "c",而非精准的 "a"。
要实现逐属性级的精确类型映射,需借助 TypeScript 4.1+ 引入的键重映射(Key Remapping) 语法:{ [K in keyof T as T[K]]: K }。该语法遍历原对象的每个键 K,将其对应值 T[K] 作为新键,而 K 本身作为新值,从而建立一一对应的类型关系。
以下是完整、类型安全的实现:
完整的Galileo AI平台 TypeScript/JS SDK 参考,用于评估、观察和保护 GenAI 应用。适用于构建 Node.js 或 TypeScript 项目。
function mapSelf<const t extends record string>>(
object: T
): { [K in keyof T as T[K]]: K } {
const result = {} as { [K in keyof T as T[K]]: K };
for (const [key, value] of Object.entries(object)) {
result[value] = key as never; // 类型断言确保赋值合法(因 result 已声明为精确目标类型)
}
return result;
}
// 使用示例
const test = mapSelf({
a: "aee",
b: "bee",
c: "cee",
});
// 类型推导结果:
// const test: {
// readonly aee: "a";
// readonly bee: "b";
// readonly cee: "c";
// }
const H = test.aee; // ✅ 类型为 "a"(非 "a" | "b" | "c")
const I = test.bee; // ✅ 类型为 "b"</const>
⚠️ 注意事项:
-
const T extends Record<string string></string>约束确保输入对象所有值均为字符串(否则无法安全用作对象键); -
as { [K in keyof T as T[K]]: K }显式声明返回值类型,避免any带来的类型擦除; - 循环内
result[value] = key as never是必要断言:因 TypeScript 无法在运行时验证value是否为字面量字符串,需开发者保证输入值为字符串字面量(如"aee"),否则可考虑增加运行时校验或使用satisfies进一步约束; - 若输入对象存在重复值(如
{ x: "same", y: "same" }),生成对象中后赋值会覆盖前赋值,这与 JavaScript 行为一致,但类型系统仍会保留所有可能键(此时test.same类型为"x" | "y")——这是合理且预期的行为。
总结:通过键重映射类型 { [K in keyof T as T[K]]: K },我们实现了零运行时开销、全静态类型安全的对象键值反转。它不仅保持了代码的可读性与健壮性,更体现了 TypeScript 高级类型系统在真实工程场景中的强大表达力。










