2

I want to type an array where the first element is always a number, and the rest of the elements are always strings, and the length as to be at least 1.

Here is my best effort:

type MyArray =
  | [number]
  | [number, string]
  | [number, string, string]
  | [number, string, string, string];

How do I make that go on forever?

2
  • I don't think you can type it the way you've described. You could do what you currently with as many unions as you actually need, or you could use a type like (number | string)[] and helper functions to extract the number from the first item and strings from the rest, or what I would do is use an object type that has { foo: number, bar: string[] } Commented Jun 28, 2019 at 20:08
  • 2
    [number, ...string[]] will work in recent versions of TypeScript. Commented Jun 28, 2019 at 20:55

1 Answer 1

2

Before TypeScript 3.0 there really wasn't anything better than a union like you have. But then a bunch of related new features were introduced to better support tuple types, and specifically their relationship to lists of function parameters. And since functions support a final rest parameter representing the type of an indefinite number of parameters as an array, it made sense to introduce a final rest element in a tuple representing the type of an indefinite number of tuple elements as an array.

Hey, in fact, your use case is explicitly mentioned as an example in the documentation:

For example, [number, ...string[]] means tuples with a number element followed by any number of string elements.

So let's try that:

type MyArray = [number, ...string[]];
const okay0: MyArray = [0]; // okay
const okay1: MyArray = [1, "a"]; // okay
const okay2: MyArray = [2, "a", "b"]; // okay
const okay3: MyArray = [3, "a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]; // okay

const bad0: MyArray = [0, "a", false]; // error!
//    ~~~~ <-- boolean is not assignable to string
const bad1: MyArray = ["x", "y"]; // error!
//                     ~~~ <-- string is not assignable to number
const bad2: MyArray = []; // error!
//    ~~~~ <--- property '0' is missing (i.e., bad2[0] is missing)

Looks good to me. Hope that helps; good luck!

Link to code

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.