Is there a way to automatically generate a type based on a dictionary value? E.g. given this dictionary of constant values:
export const SHIPMETHODS: OptionsMap<UpsShipMethodOption> = {
'UPS': 'GND',
'UPS AIR2': '2DA',
'UPS 3DAY SELECT': '3DS'
}
Is there a way to automatically generate a type like this, without having to duplicate everything?
export type ShipMethodOptionMap = {
'UPS': 'GND',
'UPS AIR2': '2DA',
'UPS 3DAY SELECT': '3DS'
}
Unfortunately keyof doesn't seem to work since it's an object and not a type, so this doesn't work:
export type UpsShipMethodOption = keyof SHIPMETHODS // Doesn't work
I also tried using mapped types with a predeclared union type of the keys, but it doesn't work either:
/*
Type 'KeyOptions' is not assignable to type 'string | number | symbol'.
Type 'KeyOptions' is not assignable to type 'symbol'.ts(2322)
*/
export type OptionsMap<KeyOptions> = {
readonly [Property in KeyOptions]: string;
}
export const SHIPMETHODS: OptionsMap<UpsShipMethodOption> = {
'UPS': 'GND',
'UPS AIR2': '2DA',
'UPS 3DAY SELECT': '3DS'
}
export type UpsShipMethodOption = 'UPS' | 'UPS AIR2' | 'UPS 3DAY SELECT'
I have a bunch of such dictionaries, and most of them are quite large (30+ keys). Duplicating the dictionary into a type everywhere would make it a pain to maintain in case the values change, so any help with this would be great!
I think you just want the typeof
operator. It simply gets the type of a value.
const SHIPMETHODS = {
'UPS': 'GND',
'UPS AIR2': '2DA',
'UPS 3DAY SELECT': '3DS'
} as const // as const is important.
type ShipMethodOptionMap = typeof SHIPMETHODS
/*
type ShipMethodOptionMap = {
readonly UPS: "GND";
readonly 'UPS AIR2': "2DA";
readonly 'UPS 3DAY SELECT': "3DS";
}
*/
type UpsShipMethodOption = keyof ShipMethodOptionMap
// type UpsShipMethodOption = "UPS" | "UPS AIR2" | "UPS 3DAY SELECT"
Just note the as const
on your object which allows typescript to infer the string literals so they can become part of the type.