cyberixae
cyberixae

Reputation: 973

Require a Specific Item in a TypeScript Array

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

Answers (1)

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

Related Questions