Correct way to handle a Partial Record with iteration not showing undefined in TypeScript?

Viewed 196

I'm trying to find the correct way to type a logical Dictionary object in TypeScript. The Record and Partial types combined do not work the way I want them to -- my "want" is to behave like a common dictionary/map available in other languages.

Given a dict: Dictionary<K,V> I want:

  • dict.key to have the type undefined|V since the key may not exist
  • Object.values(dict) to have the type Iterable<V>
  • Object.entries(dict) to have the type Iterable<[K, V]>
  • Object.keys(dict) to have the type Iterable<K>

Record<K,V> does not work, since accessing by key always yields the value type V, even though the key may not exist.

Partial<Record<K,V>> does not work, since then Object.values returns a type of Iterable<V|undefined>

How can I properly define a Dictionary type that works with standard JS objects?

It's fine if I have to override definitions of Object.values/entries/keys for a Dictionary type. I'm not clear on how I override Object functions for specific types only.

Note: I'm aware of a lot of the history of these types here. I'm interested in finding a solution that works. The above Dictionary is a common typing paradigm available in many languages, so I would like it to be possible in TypeScript.

1 Answers

At the moment there appears to be no way to properly model a Dictionary type in TypeScript.

A question on the TypeScript project indicates noUncheckedIndexedAccess as an option, but that's a global flag that goes beyond records and flags some valid array use as well.

Related