如何为泛型对象生成指定键之前的有序子集类型?
实现指定键之前的有序对象子集类型
要实现这个需求,我们可以借助TypeScript的递归类型和对字面量对象键顺序的保留特性(和V8引擎行为一致),分两步完成:先收集指定键之前的所有键,再提取这些键对应的类型子集。
具体实现代码
// 辅助类型:递归收集目标键之前的所有键,生成有序元组 type KeysUntil<T, K extends keyof T, Acc extends PropertyKey[] = []> = keyof T extends infer Keys ? Keys extends PropertyKey ? K extends Keys ? Acc : T extends Record<Keys, any> ? KeysUntil<Omit<T, Keys>, K, [...Acc, Keys]> : Acc : Acc : Acc; // 目标泛型类型:提取指定键之前的有序子集 type OrderedExtraction<T extends object, K extends keyof T> = Pick<T, KeysUntil<T, K>[number]>;
测试示例
type test = { a: number, b: number, c: number, d: number, }; // 提取"c"之前的键对应的子集 type subset = OrderedExtraction<test, "c">; // 最终 subset 类型为 { a: number; b: number }
原理说明
KeysUntil辅助类型:通过递归遍历对象类型的键,每次取出当前对象的第一个键(依赖TS对字面量对象键顺序的保留),将其加入累加元组Acc,再用Omit移除该键继续递归,直到遇到目标键K时停止,返回已收集的键元组。OrderedExtraction类型:利用Pick工具类型,从原对象类型T中提取KeysUntil返回的元组里所有键对应的类型,得到目标有序子集。
注意事项
- 该实现依赖TypeScript对字面量对象键顺序的保留行为,这和V8引擎的非官方保证一致,但ECMAScript标准并未规定对象键顺序,动态生成的对象类型可能不符合预期。
- 仅适用于直接字面量定义的对象类型,交叉类型等方式生成的对象,键顺序可能不可靠。
内容的提问来源于stack exchange,提问作者Dom C.
相关产品推荐
相关产品推荐

