Reviving polymorphic JSON
Example 1: revive based on an enumerated field
/* eg. 1: */ {"collectionType": "OBJECT", "collection": {"a": 1, "b": 2}}
/* eg. 2: */ {"collectionType": "ARRAY" , "collection": [1, 2, 3, 4, 3]}const CollectionType = M.Enum.fromArray(['OBJECT', 'ARRAY'])const {_, number, stringMap, list, anyOf} = M.metadata()
class NumberCollection extends M.Base {
getNumbers () {
const {collectionType, collection} = this
switch (collectionType()) {
case CollectionType.OBJECT():
// Note that .inner() creates a copy. For improved performance,
// [...collection()[M.symbols.innerOrigSymbol]().values()] is used
return [...collection()[M.symbols.innerOrigSymbol]().values()]
case CollectionType.ARRAY():
return [...collection()]
default:
throw TypeError(`Unsupported NumberCollection with type ${collectionType.toJSON()}`)
}
}
sum () {
return this.getNumbers().reduce((acc, x) => acc + x, 0)
}
static innerTypes () {
return Object.freeze({
collectionType: _(CollectionType),
collection: anyOf([
[stringMap(number()), CollectionType.OBJECT()],
[list(number()), CollectionType.ARRAY()]
], 'collectionType') // if omitted, the enumerated field is 'type'
})
}
}Example 2: revive based on the shape of the value
Last updated