dictionary()
ts
function dictionary<K, V>(parseKey, parseValue): Parser<string extends K ? Record<K, V> : Partial<Record<K, V>>>
Dictionaries are objects that map strings to other values.
Due to how TypeScript works, this function has two behaviors at the type level, depending on Key
(At runtime, it always behaves the same):
- When the key is
string
, it validatesRecord<string, V>
. WhennoUncheckedIndexedAccess
is enabled, TypeScript understands that a value retrieved with a string the value can beundefined
. However, the value is not semantically identical toPartial<Record<string, V>>
. - When the key is a subset of
string
, it validatesPartial<Record<K, V>>
. If the properties were not marked as optional, TypeScript would assume that all keys map to values.
Type Parameters
Type Parameter |
---|
K extends string |
V |
Parameters
Parameter | Type | Description |
---|---|---|
parseKey | Parser <K > | parses every key |
parseValue | Parser <V > | parses every value |
Returns
Parser
<string
extends K
? Record
<K
, V
> : Partial
<Record
<K
, V
>>>
a parser for a record
Examples
Validate a dictionary:
ts
const parseDictionary = dictionary(isString, isString)
parseDictionary({ hello: 'world' }) // -> Success
parseDictionary({ hello: 1 }) // -> Failure
You can transform the keys and values; for example, to only allow lowercase strings:
ts
const parseLowerCase = (data: unknown): data is Lowercase<string> =>
typeof data === 'string' ? failure('Not a string') : success(data.toLowerCase())
const parseDictionary = dictionary(parseLowerCase, parseLowerCase)
parseDictionary({ hello: 'world' }) // -> Success<{ hello: 'world' }>
parseDictionary({ Hello: 'world' }) // -> Success<{ hello: 'world' }>
parseDictionary({ hello: 'World' }) // -> Success<{ hello: 'world' }>