Reputation: 11890
I have a scenario where I have a union of different types that all have a similar signature. I want to create a mapped type so I can look up all my types by an id:
type Apple = {
name: "apple",
value: 1,
};
type Banana = {
name: "banana",
value: "foobar"
};
type Cherry = {
name: "cherry",
value: () => "hi"
};
type AllTypes = Apple | Banana | Cherry;
type AllTypeKeys = AllTypes['name'];
type TypeMap = {
"apple": Apple;
"banana": Banana;
"cherry": Cherry;
}
I can do it manually, as I have done in the TypeMap.
However, I would prefer to do something like this:
type TypeMap = {
[F['name'] in AllTypes]: F;
}
This obviously doesn't work. Is there something similar that would?
Upvotes: 4
Views: 59
Reputation: 32148
as
type TypeMap2 = {
[K in AllTypes as K['name']]: K
}
type TypeMap = {
[V in AllTypes['name']]: Extract<AllTypes, { name: V }>
}
More generic type can be defined as
type MapByKey<T, U extends keyof T > = {
[K in T as K[U] & (string | number | symbol)]: K
}
// or prior to TS 4.1
type MapByKey<T, U extends keyof T > = {
[V in T[U] & (string | number | symbol)]: Extract<T, Record<U, V>>
}
type TypeMap3 = MapByKey<AllTypes, 'name'>
Upvotes: 2