如何在 TypeScript 中定义具有交替类型的数组? [英] How to define array with alternating types in TypeScript?

查看:81
本文介绍了如何在 TypeScript 中定义具有交替类型的数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想定义一个数组类型,它允许根据位置使用不同的类型,但在某些数据结构中以重复、交替的方式进行.

示例:

[A, B, A, B, ...][A、B、C、A、B、C、...]

这可能吗?

我知道我可以为具有固定数量元素的数组定义它,如上(不带省略号),并且

(A | B)[]

另一方面,允许任何元素为 A 或 B 类型.

我试过这些:

[(A, B)...][...[A, B]][(A, B)*]

解决方案

我想出了一些有效"的东西,但它有点疯狂:

type Alternating=T 扩展只读 [] ?吨: T 扩展只读 [A] ?吨: T 扩展只读 [A, B, ...推断 T2]?T2延伸交替<T2,A,B>?: 从来没有: 绝不

由于递归条件类型,这需要 TypeScript 4.1+.


天真的用法需要将值复制为 T 参数的文字类型,这并不理想:

const x: 交替<[1, 'a', 2], number, string>= [1, 'a', 2]

这似乎比仅仅写出 [number, string, number] 作为类型更糟糕.但是,在虚拟函数的帮助下,可以避免重复:

function mustAlternate(_:交替): 空白 {}const x = [1, 'a', 2] 作为 constmustAlternate(x)

helow rel'>helow rel'>


我实际上不建议在典型的代码库中依赖它(使用起来很尴尬,而且错误消息很糟糕).我主要是通过它来查看类型系统可以扩展多远.

如果有人有关于如何让它不那么不稳定的建议,我会全神贯注!

I would like to define an array type that allows different types depending on position, but in a repeating, alternating manner as found in some data structures.

Example:

[A, B, A, B, ...]
[A, B, C, A, B, C, ...]

Is this possible?

I know that I can define it for arrays with a fixed number of elements like above (without the ellipsis), and

(A | B)[]

would on the other hand allow any element to be either of type A or B.

I tried these:

[(A, B)...]
[...[A, B]]
[(A, B)*]

解决方案

I came up with something that "works", but it's kinda crazy:

type Alternating<T extends readonly any[], A, B> =
  T extends readonly [] ? T
  : T extends readonly [A] ? T
  : T extends readonly [A, B, ...infer T2]
    ? T2 extends Alternating<T2, A, B> ? T : never
  : never

This requires TypeScript 4.1+ because of the recursive conditional type.


Naive usage requires duplicating the value as a literal type for the T parameter, which is not ideal:

const x: Alternating<[1, 'a', 2], number, string> = [1, 'a', 2]

That seems strictly worse than just writing out [number, string, number] as the type. However with the help of a dummy function it's possible to avoid repetition:

function mustAlternate<T extends readonly any[], A, B>(
  _: Alternating<T, A, B>
): void {}

const x = [1, 'a', 2] as const
mustAlternate<typeof x, number, string>(x)

Here's a live demo with some test cases.


I wouldn't actually recommend relying on this in typical codebases (it's awkward to use and the error messages are terrible). I mostly just worked through it to see how far the type system could be stretched.

If anyone has suggestions for how to make it less wonky, I'm all ears!

这篇关于如何在 TypeScript 中定义具有交替类型的数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆