我一直在try 为基于流的系统开发类型,其中流中 node 的输出必须进入另一个 node 的"正确"输入.每个 node 都被实现为FlowNode<Inputs extends any[], Output extends any>.

要使其有效类型化,每个流 node 只能输出到以下类型的链接:

type ValidLink = [FlowNode<OtherInputs, any>, I]
// where
//   I extends number
//   OtherInputs[I] extends Output

可以将这个问题简化为实现泛型类型的问题:

type ValidlyIndexed<X> = [Tuple, I]
// where
//   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>

如果它有任何帮助,那么解决方案here非常接近,但我不确定如何表示所有元组类型的联合.

如果这个问题有任何模棱两可的地方,请随时发表 comments ,我会尽我所能澄清这些问题.

推荐答案

在没有访问实际类型的情况下,类型不能声明其子类型之间的关系.

这意味着:

[[boolean, number], 0] extends ValidlyIndexed<boolean>

不可能是真的,因为ValidlyIndexed看不到[[boolean, number], 0]类型.

因此,ValidlyIndexed需要将它正在判断的类型作为泛型类型参数接收.一旦你这样做了,你就可以用第二个通用约束来验证它是正确的.

type ValidlyIndexed<T extends [unknown[], number], X extends T[0][T[1]]> = T

该类型接受索引元组为T,并接受在索引处进行验证的类型.

这一点:

X extends T[0][T[1]]

将只允许上述索引处的类型有效.

  • T[0]获取T的第一个元素,即内部元组.
  • T[1]获取标记的索引(或索引联合)
  • 因此,T[0][T[1]]通过标记索引来索引内部元组,这提供了这些索引处的类型的联合.

现在,如果您判断的X类型不正确,就是类型错误:

type A1 = ValidlyIndexed<[[boolean, number], 0], boolean> // fine
type A2 = ValidlyIndexed<[[boolean, number], 1], boolean> // Type 'boolean' does not satisfy the constraint 'number'.(2344)
type A3 = ValidlyIndexed<[[boolean, number], 1], number> // fine

type B1 = ValidlyIndexed<[[number, boolean, number, string], 0 | 2], number> // fine
type B2 = ValidlyIndexed<[[number, boolean, number, string], 0 | 2], string> // Type 'string' does not satisfy the constraint 'number'.(2344)

type C = ValidlyIndexed<[['a' | 'b', string, 'b', 'c'], 0 | 1 | 2], 'b'> // fine

See Playground

Typescript相关问答推荐

如何将绑定到实例的类方法复制到类型脚本中的普通对象?

您可以创建一个类型来表示打字员吗

类型安全JSON解析

如何在排版中正确键入中间件链和控制器链

单击并移除for循环中的一项也会影响另一项

带下拉菜单的Angular 响应式选项卡

错误TS2403:后续变量声明必须具有相同的类型.变量';CRYPTO';的类型必须是';CRYPATO';,但这里的类型是';CRYPATO';

垫表页脚角v15

如何将TS泛型用于react-hook-form接口?

有没有办法在Zod中使用跨字段验证来判断其他字段,然后呈现条件

接受字符串或数字的排序函数

为什么在泛型方法中解析此promise 时会出现类型错误?

Rxjs将省略的可观测对象合并到一个数组中

对于VUE3,错误XX不存在于从不存在的类型上意味着什么?

垫子工具栏不起作用的Angular 布线

在打印脚本中将对象类型转换为数组

仅当定义了值时才按值筛选数组

如何为对象数组中的每个条目推断不同的泛型

如何使用布尔值构建对象 TYPE,但至少有一个必须为 true

如果父级被删除或删除,如何自动删除子级?