如何在TypeScript中基于对象键值进行条件类型判断?
基于对象键条件检查的TypeScript类型定义问题
你尝试为如下结构的对象定义TypeScript类型:
{ entrées: [{ id: '1', 'name': 'a' }], plats: [{ id: '2', 'name': 'b' }], accompagnements: [{ id: '3', 'name': 'c' }], menu: [{ id: '4', config: [...] }] }
使用了以下类型定义后触发错误:
type MockData = { [key: string]: key extends 'menu' ? MenuEntry[] : CommonEntry[]; };
错误提示:
key refers to a value, but is being used as a type here
问题根源
普通对象索引签名中的key是值层面的变量,无法在类型条件判断中直接使用。要实现基于键的条件类型逻辑,必须使用映射类型(Mapped Types)——这是TypeScript中专门用于在类型层面遍历键并应用逻辑的语法。
正确实现方案
方案1:固定键的精确映射
如果对象的键是固定已知的,先定义键的联合类型,再通过映射类型遍历并应用条件:
// 先定义对象的所有键 type MockDataKeys = 'entrées' | 'plats' | 'accompagnements' | 'menu'; // 映射类型实现条件判断 type MockData = { [K in MockDataKeys]: K extends 'menu' ? MenuEntry[] : CommonEntry[]; };
此方案会为每个指定键生成精确类型:menu对应MenuEntry[],其余键对应CommonEntry[]。
方案2:兼容额外未知键
如果需要允许对象包含其他任意字符串键,且这些键的类型统一为CommonEntry[],可以结合Record类型实现:
type MockData = { // 单独指定menu键的类型 menu: MenuEntry[]; } & Record<string, CommonEntry[]>;
这种写法既保证menu键的类型正确性,又兼容其他未知字符串键的场景。
补充:基础类型定义
确保你已提前定义CommonEntry和MenuEntry的基础类型,示例如下:
type CommonEntry = { id: string; name: string; }; type MenuEntry = { id: string; config: unknown[]; // 根据实际业务需求替换为具体类型 };
内容的提问来源于stack exchange,提问作者Lin Shen
相关产品推荐
相关产品推荐

