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
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 anumber
element followed by any number ofstring
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