Reputation: 37228
A library I'm using exports a type like this:
type Pet = 'dog' | 'cat' | 'rat';
I want to now make a dropdown that has all these values in my UI. I am not able to enumerate this const type. So I thought to make an array of these values and type it such that it must have exactly one of each const in the type Pet
but can't figure this out.
I tried the following but it doesn't cause error when more keys are added to Pet
. I want typescript to fail on build when I update the lib and the lib decided to add more consts.
type Pet = 'dog' | 'cat' | 'rat';
const pets: Pet[] = ['dog', 'dog']; // this should error as its missing "cat" and "rat". and also it has "dog" twice.
Upvotes: 0
Views: 64
Reputation: 9893
Based on this if you use TypeScript 4.1
or later you can do like this:
type UniqueArray<T> =
T extends readonly [infer X, ...infer Rest]
? InArray<Rest, X> extends true
? ['Encountered value with duplicates:', X]
: readonly [X, ...UniqueArray<Rest>]
: T
type InArray<T, X> =
T extends readonly [X, ...infer _Rest]
? true
: T extends readonly [X]
? true
: T extends readonly [infer _, ...infer Rest]
? InArray<Rest, X>
: false
const data = ['dog', 'cat' , 'rat'] as const
const uniqueData: UniqueArray<typeof data> = data
const pets: UniqueArray <typeof data> = ['dog', 'dog']; // this should error as its missing "cat" and "rat". and also it has "dog" twice.
Here is working code.
Upvotes: 1