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

如何创建既强制含所有键又能推断值类型的TypeScript映射?

如何创建强制包含指定所有键且自动推断值类型的TypeScript映射

假设我们有如下键类型:

type State = "OPEN" | "CLOSED";

方案一:使用无类型object

const stateToNaturalLangMap = {
  OPEN: "open",
  CLOSED: "closed"
} as const;

// "OPEN" | "CLOSED"
type KeysOfMap = keyof typeof stateToNaturalLangMap;

// "open" | "closed"
type ValuesOfMap = (typeof stateToNaturalLangMap)[keyof typeof stateToNaturalLangMap];

该方案能自动推断键和值的具体类型,但无法强制映射包含所有指定的State键,也不能限制额外键的添加。

方案二:使用Record

const stateToNaturalLangRecord: Record<State, string> = {
  OPEN: "open",
  CLOSED: "closed"
} as const;

// "OPEN" | "CLOSED"
type KeysOfRecord = keyof typeof stateToNaturalLangRecord;

// string
type ValuesOfRecord = (typeof stateToNaturalLangRecord)[keyof typeof stateToNaturalLangRecord];

该方案刚好相反:它强制映射包含所有State键,且不允许添加额外键,但无法推断值的具体类型,值类型只能被识别为宽泛的string。

正确解决方案

方法1:泛型函数约束(兼容全版本TypeScript)

通过泛型函数实现类型约束与类型推断的兼顾:

type State = "OPEN" | "CLOSED";

function createStateMap<T extends Record<State, string>>(map: T): T {
  return map;
}

const stateToNaturalLang = createStateMap({
  OPEN: "open",
  CLOSED: "closed"
} as const);

// "OPEN" | "CLOSED"
type KeysOfMap = keyof typeof stateToNaturalLang;

// "open" | "closed"
type ValuesOfMap = (typeof stateToNaturalLang)[keyof typeof stateToNaturalLang];

这里用T extends Record<State, string>约束传入对象必须包含所有State键,同时返回类型为T以保留值的具体类型。若遗漏State键或添加额外键,TypeScript会直接报错;值的类型也会被精确推断为字面量类型。

方法2:satisfies运算符(TypeScript 4.9+)

利用satisfies运算符可以更简洁地实现需求:

type State = "OPEN" | "CLOSED";

const stateToNaturalLang = {
  OPEN: "open",
  CLOSED: "closed"
} as const satisfies Record<State, string>;

// "OPEN" | "CLOSED"
type KeysOfMap = keyof typeof stateToNaturalLang;

// "open" | "closed"
type ValuesOfMap = (typeof stateToNaturalLang)[keyof typeof stateToNaturalLang];

satisfies会检查对象是否符合指定类型,但不会覆盖对象的原始类型推断,完美实现了“强制包含指定键+自动推断值类型”的双重需求。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 11:38:23