Inspiration is from this article https://levelup.gitconnected.com/building-type-safe-dictionaries-in-typescript-a072d750cbdf as well as practical problem that we encountered in our codebase.
If we want a type-safe dictionary where key is e.g. string we can simply use a Record:
constx: Record<string,number>={}However, if we want to restrict set of keys:
Then suddenly TypeScript requires all keys to be present:
// Does not compileconstx: Record<Key,number>={}The only solution seems to be to allow undefined values with Partial:
constx: Partial<Record<Key,number>>={}However, this now breaks Object.values and in general it's not good because the type of value becomes number | undefined, which is not what we want.
Another issue is with Object.entries and Object.keys which are not type-safe either.
Suggestion
Support first-class type-safe dictionaries where set of keys is finite:
constx: Dict<Key,number>={}and provide type-safe Object.keys, Object.values and Object.entries.
Dict says that:
- Keys must be of type
K. - Not all keys may be present.
- Type of value is
V.
Note that this is only about type-safety, Dict is still a plain JavaScript object.
Inspiration is from this article https://levelup.gitconnected.com/building-type-safe-dictionaries-in-typescript-a072d750cbdf as well as practical problem that we encountered in our codebase.
If we want a type-safe dictionary where key is e.g. string we can simply use a
Record:However, if we want to restrict set of keys:
Then suddenly TypeScript requires all keys to be present:
The only solution seems to be to allow
undefinedvalues withPartial:However, this now breaks
Object.valuesand in general it's not good because the type of value becomesnumber | undefined, which is not what we want.Another issue is with
Object.entriesandObject.keyswhich are not type-safe either.Suggestion
Support first-class type-safe dictionaries where set of keys is finite:
and provide type-safe
Object.keys,Object.valuesandObject.entries.Dictsays that:K.V.Note that this is only about type-safety,
Dictis still a plain JavaScript object.