Provides functions to extract data from an unknown data structure as is
typically produced by JSON.parse(sometext).
All methods typically return a Maybe<T> which is either the
expected result type or a JsonAccessError. To easily combine the
methods, they also accept Maybe<unknown>, and in case it is indeed
an error, it is immediately returned.
NOTE: While the functions are called json..., the input
is not a string but the output of jsonParse of type
unknown. Insofar the functions can generally be used to savely pick
typed values out of unknown data, whether produced by JSON.parse() or not.
There are four sets of functions:
jsonAsX
These check if a given value is of type X and return
the value or a JsonAccessError. For a data: unknown this looks like
These check that data is an object with a given field or an array with a
given index, get the value and then call the respective jsonAsX. If we
expect data to be an object with a field size holding a number, we
use:
Consider jsonGetNumber(data, 'size') with its two parameters. It fetches the
field size from data if possible, and then tries to convert it to a
number (per jsonAsNumber). Assume we need a sizeGetter(data). We could
write sizeGetter = (data) => jsonGetNumber(data, 'size'), but a slightly
less verbose and possibly better readable definition is:
constsizeGetter = jsonNumberGetter('size');
The sizeGetter can be used as an extractor as needed for jsonTypeConverter.
Consider an API which is expected to deliver an object like
{ item: string, price: number} and we want to savely access the values.
consttext = '{"id": "socks", "price": 3.14}'; constdata = jsonParse(text); typeItem = { id: string; price: number }; constitem: Maybe<Item> = jsonAsType( data, [jsonStringGetter('id'), jsonNumberGetter('price')], (id, p) => ({ id:id, price:p }) ); if (!isValid(item)) { throwitem; // a JsonAccessError } // continue with item properly typed as Item
Instead of using type Item one could create a respective class,
use jsonAsInstance and pass the constructor as the third parameter
instead of the elaborate lambda to create the item.
Provides functions to extract data from an unknown data structure as is typically produced by
JSON.parse(sometext).All methods typically return a Maybe
<T>which is either the expected result type or a JsonAccessError. To easily combine the methods, they also acceptMaybe<unknown>, and in case it is indeed an error, it is immediately returned.There are four sets of functions:
jsonAsX
These check if a given value is of type X and return the value or a
JsonAccessError. For adata: unknownthis looks likeSee jsonAsString, jsonAsNumber, jsonAsNumberType, jsonAsBoolean, jsonAsObject, jsonAsArray, jsonAsTypedArray, jsonAsType, jsonAsInstance, jsonAsUnion.
jsonGetX
These check that
datais an object with a given field or an array with a given index, get the value and then call the respectivejsonAsX. If we expectdatato be an object with a fieldsizeholding a number, we use:See jsonGetString, jsonGetNumber, jsonGetNumberType, jsonGetBoolean, jsonGetObject, jsonGetArray, jsonGetTypedArray, jsonGetType, jsonGetInstance, jsonGetUnion.
jsonXxxConverter
These are functions to generate a
jsonAsXfor an arbitraryX, where theXis not covered by the predefinedjsonAsNumberetc. functions. Example:The generated functions are intented to be used, for example as a parameter of jsonAsInstance. There are three of them jsonTypedArrayConverter, jsonTypeConverter, jsonInstanceConverter.
jsonXxxGetter
Consider
jsonGetNumber(data, 'size')with its two parameters. It fetches the fieldsizefromdataif possible, and then tries to convert it to a number (perjsonAsNumber). Assume we need asizeGetter(data). We could writesizeGetter = (data) => jsonGetNumber(data, 'size'), but a slightly less verbose and possibly better readable definition is:The
sizeGettercan be used as an extractor as needed for jsonTypeConverter.See jsonStringGetter, jsonNumberGetter, jsonNumberTypeGetter, jsonBooleanGetter, jsonObjectGetter, jsonArrayGetter, jsonTypedArrayGetter, jsonTypeGetter, jsonInstanceGetter.
Example
Consider an API which is expected to deliver an object like
{ item: string, price: number}and we want to savely access the values.Instead of using
type Itemone could create a respective class, use jsonAsInstance and pass the constructor as the third parameter instead of the elaborate lambda to create the item.