TypeScript中提取不匹配字段及从常量数组提取字段联合类型的实现方案咨询
通用可扩展的TypeScript字段提取方案
嘿,这个场景我太熟悉了——手动写一堆Extract分支确实太死板了,数据结构一变就得改类型代码,完全不具备扩展性。下面给你一套通用的解决方案,不管你的数据集怎么加新结构,都能自动提取目标字段~
核心思路
我们的目标是:自动遍历data数组里的每个对象,提取除type外所有属性的字面量值,最后合并成联合类型。利用TypeScript的条件类型、类型推断和映射类型就能实现这个需求。
实现代码
首先定义一个通用的类型工具,用来处理单个对象的字段提取:
// 提取单个对象中除type外的所有属性值 type ExtractFieldValues<T> = T extends { type: infer _; [K in Exclude<keyof T, 'type'>]: infer V } ? V : never;
然后直接对data的元素联合类型应用这个工具:
const data = [ {type: 'text', field: 'name'}, {type: 'minMax', minField: 'min', maxField: 'max'} ] as const; // 得到 'name' | 'min' | 'max' type AllFields = ExtractFieldValues<typeof data[number]>;
为什么这个方案具备扩展性?
假设你后续给data新增一个元素,比如:
const data = [ {type: 'text', field: 'name'}, {type: 'minMax', minField: 'min', maxField: 'max'}, {type: 'select', optionField: 'selectedOption'} // 新增结构 ] as const;
不需要修改ExtractFieldValues类型,AllFields会自动变成'name' | 'min' | 'max' | 'selectedOption',完全适配结构变化。
处理“不匹配字段”的提取需求
如果你需要过滤掉不符合特定规则的字段(比如只提取字符串类型的字段值,排除数字/布尔等类型),可以给类型工具加个约束:
// 只提取字符串类型的字段值 type ExtractStringFieldValues<T> = T extends { type: infer _; [K in Exclude<keyof T, 'type'>]: infer V } ? V extends string ? V : never : never;
比如如果某个对象里有{type: 'number', value: 123},这个字段值123就会被过滤掉,不会出现在最终的联合类型里。
关键细节说明
- 一定要用
as const断言:它会把data里的所有属性值锁定为字面量类型(比如'name'而不是string),这样我们才能提取到具体的字段名,而不是宽泛的string类型。 Exclude<keyof T, 'type'>:用来排除每个对象里的type属性,只处理我们关心的字段属性。- 条件类型自动分发:当
T是联合类型时(比如typeof data[number]就是两个对象的联合),TypeScript会自动对每个联合成员单独应用条件类型,最后合并结果。
内容的提问来源于stack exchange,提问作者Daaavvy
相关产品推荐
相关产品推荐

