Based on this answer, I think that this solves your problem:
type Country = "uk" | "france" | "india";
type MapOfKeysOf<U extends string> = {
[key in U]: MapOfKeysOf<Exclude<U, key>>;
}
type ExhaustiveArrayOfObjects<Keys extends {[key: string]: {}}, T = {}, KeyName extends string = "value"> = {} extends Keys ? [] : {
[key in keyof Keys]: [T & Record<KeyName, key>, ...ExhaustiveArrayOfObjects<Keys[key], T, KeyName>];
}[keyof Keys]
export const data: ExhaustiveArrayOfObjects<MapOfKeysOf<Country>> = [
{
value: 'uk',
},
{
value: 'france',
},
{
value: 'india',
}
]
If you want, you can pass an extra type to extends or event customize the prop that will hold de value
type Country = "uk" | "france" | "india";
type MapOfKeysOf<U extends string> = {
[key in U]: MapOfKeysOf<Exclude<U, key>>;
}
type ExhaustiveArrayOfObjects<Keys extends {[key: string]: {}}, T = {}, KeyName extends string = "value"> = {} extends Keys ? [] : {
[key in keyof Keys]: [T & Record<KeyName, key>, ...ExhaustiveArrayOfObjects<Keys[key], T, KeyName>];
}[keyof Keys]
type Option = {
label: string,
id: Country
}
const data: ExhaustiveArrayOfObjects<MapOfKeysOf<Country>, Option, "id"> = [
{
label: "United Kingdom",
id: 'uk',
},
{
label: "France",
id: 'france',
},
{
label: "India",
id: 'india',
}
]
const option: Option = data[0]
You can check more on this playgroud