Let's say that I want to enforce strict typing on a given array, such that:
- It may contain any number (a.k.a. zero or more) of
number
- It must contain one number or more of
string
...and the order of number
and string
in the array does not matter, so that the following arrays are valid:
['foo', 1, 2, 3]
[1, 2, 'foo', 3]
['foo']
But the following array is invalid:
[1, 2, 3]
(because it needs at least onestring
in the array)
The closest solution that almost worked for me is to define the type as:
/**
* Array must contain:
* - One or more string
* - Zero or more numbers
* @type
*/
type CustomArray = [string] & Array<number | string>
const a: CustomArray = ['foo', 1, 2, 3]; // Should pass (works as expected)
const b: CustomArray = [1, 2, 'foo', 3]; // Should pass (but doesn't with my code)
const c: CustomArray = ['string']; // Should pass (works as expected)
const d: CustomArray = [1, 2, 3]; // Should fail (works as expected)
But this means that the first element of the array must be a string, instead of enforcing a minimum count of 1 throughout the array. You can test it out on TypeScript Playround here.