Reputation: 973
How do I write a requirement for a specific item in a typescript array? Let's consider for example "number array with atleast one number seven". It seems that requiring a specific element to be seven is easy but requiring "one of the elements" is more difficult.
I tried the following. However, it produces Type alias 'ContainsSeven' circularly references itself. ts(2456)
error.
type ContainsSeven =
|[7, ...Array<number>]
|[number, ...ContainsSeven]
const example1: ContainsSeven = [1,2,7]
const example2: ContainsSeven = [1,7,2]
const example3: ContainsSeven = [7,1,2]
// @ts-expect-error
const counter1: ContainsSeven = []
// @ts-expect-error
const counter2: ContainsSeven = [1,2,3]
My ultimate goal is to use standard JavaScript Arrays instead of a custom linked structure to implement lazy concatenation of generators. See related diff for a more comprehensive example.
Upvotes: 2
Views: 941
Reputation: 33051
It is doable but with function helper:
type IsValid<T extends number[]> = 7 extends T[number] ? T : never
const withSeven = <T extends number, List extends T[]>(list: IsValid<[...List]>) => list
withSeven([1, 2, 3, 4, 5, 7]) // ok
withSeven([1, 2, 3, 4, 5]) // error
IsValid
checks if one of element of the array is 7. If it is 7 - return array, otherwise - return never
.
More about type validation you can find in my here and here
Regarding circularly references
, I'd willing to bet that this question/answer are related to your problem
Upvotes: 2