如何创建既强制含所有键又能推断值类型的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
相关产品推荐
相关产品推荐

