如何实现TypeScript的ValidlyIndexed泛型类型?
问题描述
我正在为基于流的系统开发类型校验逻辑,要求流中节点的输出必须接入另一节点的「正确」输入。每个节点以FlowNode<Inputs extends any[], Output extends any>实现。
为实现合法类型校验,每个流节点只能输出到如下类型的链接:
type ValidLink = [FlowNode<OtherInputs, any>, I] // 其中 // I extends number // OtherInputs[I] extends Output
该问题可简化为实现如下泛型类型:
type ValidlyIndexed<X> = [Tuple, I] // 其中 // Tuple extends any[] // I extends number // Tuple[I] extends X
例如,以下所有类型在TypeScript中均应合法:
[[boolean, number], 0 ] extends ValidlyIndexed<boolean> [[number, boolean, number, string], 0 | 2 ] extends ValidlyIndexed<number> [['a' | 'b', string, 'b', 'c'], 0 | 1 | 2] extends ValidlyIndexed<'b'>
需要在TypeScript中实现ValidlyIndexed<X>,核心难点是如何表示所有符合条件的元组与索引对的联合类型。
解决方案
实现思路
要实现ValidlyIndexed<X>,需要完成两步:
- 遍历任意元组的所有索引,筛选出对应元素满足类型匹配条件的索引;
- 将所有符合条件的「元组+有效索引」对组合成联合类型。
代码实现
根据示例的实际匹配逻辑(X可赋值给元组对应位置元素),实现如下:
// 辅助类型:获取元组中所有满足 X extends Tuple[K] 的索引 type ValidIndices<T extends any[], X> = { [K in keyof T]: X extends T[K] ? K : never }[number]; // 目标泛型类型:所有符合条件的 [Tuple, 有效索引] 对的联合 type ValidlyIndexed<X> = { [T in any[]]: [T, ValidIndices<T, X>] }[any[]];
示例验证
将示例代入验证,均符合预期:
// 验证1:返回 true type Test1 = [[boolean, number], 0] extends ValidlyIndexed<boolean> ? true : false; // 验证2:返回 true type Test2 = [[number, boolean, number, string], 0 | 2] extends ValidlyIndexed<number> ? true : false; // 验证3:返回 true type Test3 = [['a' | 'b', string, 'b', 'c'], 0 | 1 | 2] extends ValidlyIndexed<'b'> ? true : false;
原注释条件适配
若需严格遵循原问题注释中的Tuple[I] extends X条件,只需修改辅助类型的判断逻辑:
type ValidIndices<T extends any[], X> = { [K in keyof T]: T[K] extends X ? K : never }[number];
内容的提问来源于stack exchange,提问作者Just Helpful
相关产品推荐
相关产品推荐

