I have a union and object like this:
type FilterType = 'equals' | 'notEquals';
const labelMap: {[filterType in FilterType]: string} = {
equals: 'Equals',
notEquals: 'Not Equals',
} as const;
And I would like to derive from this the equivalent of:
type Labels = 'Equals' | 'Not Equals';
The closest I've been able to get to this is:
type Labels = labelMap[keyof labelMap];
This works if I remove the {[filterType in FilterType]: string}
annotation, but I'd like to keep that so if we add new filters, we'll be forced to add a label.
How can I annotate the type of the keys of the object and also extract out the values? I could make the values their own explicit type then use:
const labelMap: {[filterType in FilterType]: ValueType} = {
But I'd prefer to keep it centralized if possible so you don't need to go to multiple places just to add a new filter.
Just use the satisfies
operator:
type FilterType = 'equals' | 'notEquals';
const labelMap = {
equals: 'Equals',
notEquals: 'Not Equals',
} as const satisfies Record<FilterType, string>;
If you add a new element to the union you'll see an error if you don't add the corresponding entry in labelMap
.
Note that your annotation is "wrong":
type MappedType = {[filterType in FilterType]: string}
const bad: MappedType = {
equals: 'Not Equals',
notEquals: 'Equals',
} // Oops!
Since it doesn't preserve the mapping between keys and values!