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

如何在TypeScript中实现类型安全的双向映射函数?

类型安全的双向映射函数实现(TypeScript)

问题背景

需要实现两组词汇的双向映射(例如 GB ↔ United_Kingdom、FR ↔ France),要求仅定义一次映射关系,就能生成两个方向的类型安全转换函数,确保输入输出的类型能被TypeScript精确推导(比如输入"a"时返回类型"A",而非"A"|"B")。

原JavaScript版本可实现功能,但无类型保障:

function createMappers(map) {
  const invertedMap = Object.entries(map).reduce(
    (inverted, [key, value]) => ({ ...inverted, [value]: key }),
    {},
  );
  const leftToRight = (from) => map[from];
  const rightToLeft = (to) => invertedMap[to];

  return [leftToRight, rightToLeft];
}

const map = { a: "A", b: "B" };
const [toRight, toLeft] = createMappers(map);

const one = toRight("a"); // 期望类型为 "A",但实际无类型约束
const two = toLeft("B"); // 期望类型为 "b",但实际无类型约束

TypeScript解决方案

通过泛型、类型断言和条件类型,我们可以实现完全类型安全的双向映射:

function createMappers<T extends Readonly<Record<string, string>>>(map: T) {
  // 构建反转映射并指定类型
  const invertedMap = Object.entries(map).reduce(
    (acc, [key, value]) => ({ ...acc, [value]: key }),
    {} as { [V in T[keyof T]]: keyof T }
  );

  // 左→右转换:输入为T的键,输出对应精确值类型
  const toRight = <K extends keyof T>(key: K): T[K] => map[key];

  // 右→左转换:输入为T的值,输出对应精确键类型
  const toLeft = <V extends T[keyof T]>(value: V): 
    Extract<keyof T, { [K in keyof T]: T[K] extends V ? K : never }[keyof T]> => 
    invertedMap[value];

  // 使用as const确保返回的元组类型被固定
  return [toRight, toLeft] as const;
}

// 定义映射时用as const断言,保留字面量类型
const countryMap = { GB: "United_Kingdom", FR: "France", a: "A", b: "B" } as const;

const [codeToName, nameToCode] = createMappers(countryMap);

// 类型推导完全精确
const ukName = codeToName("GB"); // 类型为 "United_Kingdom"
const frCode = nameToCode("France"); // 类型为 "FR"
const valA = codeToName("a"); // 类型为 "A"
const keyB = nameToCode("B"); // 类型为 "b"

// 错误输入会被TypeScript即时报错
// codeToName("US"); // 类型错误:"US" 不在 keyof typeof countryMap 中
// nameToCode("Germany"); // 类型错误:"Germany" 不在 typeof countryMap[keyof typeof countryMap] 中

核心要点

  1. as const断言映射对象:确保TypeScript将映射的键和值视为只读字面量类型,而非宽泛的string,为精确类型推导提供基础。
  2. 泛型约束T:限制输入为只读的字符串键值对对象,避免非法输入。
  3. 反转映射的类型定义:通过{ [V in T[keyof T]]: keyof T }明确反转映射的键值类型关系。
  4. 精确类型推导:
    • toRight函数利用泛型K extends keyof T,让输入键对应的输出值类型精确到具体字面量。
    • toLeft函数通过条件类型和Extract工具类型,根据输入的值反向推导出对应的键类型,实现双向的精确映射。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 15:35:26