'Can Typescript ensure arrays have a repeating type pattern? e.g. [string, number, string, number, ....(forever)]

I have a function, which I want to ensure takes a string, followed by a number. And optionally, more string number pairs. So like a tuple, but "infinite" times:

const fn = (...args: [string, number] |
[string, number, string, number] |
[string, number, string, number, string, number] |
[string, number, string, number, string, number, string, number] | ...etc etc) => {}

and so on

An alternative psuedo type construction:

type Pair = [string, number, ...Pair];

Is this possible with TypeScript?

EDIT This looks like it should work, but doesn't. TypeScript does not seem to infer the order of the pairs correctly.

type Pair = [string, number, ...Pair[]];


Solution 1:[1]

I believe so. You would define the type as

type RecurringTuple = [string, number, RecurringTuple[]];
const fn = (...args: RecurringTuple) => {}

Haven't tested, but found a similar case in this link.

Solution 2:[2]

This isn't ideal, as it only allows up to 30 array elements but I couldn't find a way to make it infinite.

However this type does ensure the order, and that they have to appear as a pair.

TypeScript 4.1 minimum , TypesScript 4.5 seems to allow for more array elements.

type Tuple<T = any, R = any> = [T, R] | [];

type Concat<T = []> = T extends [infer A, ...infer Rest]
  ? A extends any[] ? [...A, ...Concat<Rest>] : A
  : T;

type RecurringTuple<T, R> = Concat<[
  Tuple<T, R>, Tuple<T, R>, Tuple<T, R>, Tuple<T, R>, Tuple<T, R>, 
  Tuple<T, R>, Tuple<T, R>, Tuple<T, R>, Tuple<T, R>, Tuple<T, R>,
  Tuple<T, R>, Tuple<T, R>, Tuple<T, R>, Tuple<T, R>, Tuple<T, R>
]>;

const a:RecurringTuple<string, number> = ['a', 1];
const b:RecurringTuple<string, number> = ['a', 1, 'b', 2];
const c:RecurringTuple<string, number> = ['a', 1, 'b', 2, 'c', 3];
const d:RecurringTuple<string, number> = ['a', 1, 'b', 2, 'c', 3, 'd', 4];

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 joshwilsonvu
Solution 2 Will Hawker