如何移除元组指定索引及之前元素的可选标记
实现
RequiredTupleUpToAndIncluding工具类型 可以通过递归遍历元组、判断元素可选性并针对性处理的方式实现需求,同时保留元组标签、支持带剩余元素的元组,并且区分“可选标记带来的undefined”和“元素本身包含的undefined”。
完整实现代码
// 判断元组指定索引的元素是否为可选项 type IsTupleElementOptional<T extends any[], I extends number, _Acc extends any[] = []> = _Acc['length'] extends I ? T extends [..._Acc, infer E?, ...any[]] ? true : false : T extends [..._Acc, infer E, ...infer R] ? IsTupleElementOptional<[..._Acc, E, ...R], I, [..._Acc, E]> : false; // 处理单个元组元素:可选项移除undefined,必填项保持原类型 type ProcessTupleElement<T, IsOptional extends boolean> = IsOptional extends true ? Exclude<T, undefined> : T; // 递归构建处理后的元组,保留标签与剩余元素 type BuildRequiredTuple< N extends number, T extends any[], _Acc extends any[] = [], _Idx extends number = _Acc['length'] > = _Idx extends N | T['length'] ? [..._Acc, ...T] : T extends [infer E, ...infer R] ? T extends [tag: infer E, ...infer R] ? BuildRequiredTuple< N, R, [..._Acc, tag: ProcessTupleElement<E, IsTupleElementOptional<T, _Idx>>], [..._Acc, E]['length'] > : BuildRequiredTuple< N, R, [..._Acc, ProcessTupleElement<E, IsTupleElementOptional<T, _Idx>>], [..._Acc, E]['length'] > : _Acc; // 最终工具类型 type RequiredTupleUpToAndIncluding<N extends number, T extends any[]> = BuildRequiredTuple<N, T>;
测试验证
// 测试常规有限元组 type Test1 = RequiredTupleUpToAndIncluding<1, [a: '1', b?: '2', c?: '3']>; // 结果:[a: '1', b: '2', c?: '3'] // 测试带剩余元素的元组 type Test2 = RequiredTupleUpToAndIncluding<1, [a: 1, b?: 2, c?: 3, ...d: 4[]]>; // 结果:[a: 1, b: 2, c?: 3, ...d: 4[]] // 测试本身包含undefined的必填元素 type Test3 = RequiredTupleUpToAndIncluding<1, [a: '1' | undefined, '2' | undefined, '3' | undefined]>; // 结果:[a: "1" | undefined, "2" | undefined, "3" | undefined]
实现说明
IsTupleElementOptional:递归遍历元组,判断指定索引的元素是否带有可选标记(?),以此区分“可选项自带的undefined”和“元素类型本身包含的undefined”。ProcessTupleElement:根据元素是否为可选项,决定是否移除undefined——仅当元素是可选项时移除,必填项则保留原类型。BuildRequiredTuple:递归构建新元组,处理索引0到N的元素为必填,保留元组标签,剩余元素(包括剩余元素语法...)保持原样。
内容的提问来源于stack exchange,提问作者zedryas
相关产品推荐
相关产品推荐

