How can I construct a map that enforces the presence of all keys while still allowing the inference of the types of its values?
If I have certain keys, for example:
type State = "OPEN" | "CLOSED";
Method 1: using an untyped object
const stateToNaturalLangMap = {
OPEN: "open",
CLOSED: "closed"
} as const;
// "OPEN" | "CLOSED"
type KeysOfMap = keyof typeof stateToNaturalLangMap;
// "open" | "closed"
type ValuesOfMap = (typeof stateToNaturalLangMap)[keyof typeof stateToNaturalLangMap];
Method 1 allows for the inference of key and value types, but it does not enforce the inclusion of all keys in the map (or the addition of extra keys).
Method 2: using Record
const stateToNaturalLangRecord: Record<State, string> = {
OPEN: "open",
CLOSED: "closed"
} as const;
// "OPEN" | "CLOSED"
type KeysOfRecord = keyof typeof stateToNaturalLangRecord;
// string
type ValuesOfRecord = (typeof stateToNaturalLangRecord)[keyof typeof stateToNaturalLangRecord];
Method 2, on the other hand, ensures that all keys are part of the map (and prevents the addition of other keys), but it does not allow the inference of value types (the type of values is string
).