A decoder that accepts anything.
Create a decoder for booleans.
Example:
Decoder.boolean.run(true) // succeeds
Decoder.boolean.run('false') // succeeds
Decoder.boolean.run(1) // fails
A decoder that accepts a Buffer.
Example:
Decoder.buffer.run(undefined) // FAIL
Decoder.buffer.run(5) // FAIL
Decoder.buffer.run(Buffer.from('Hello world')) // OK
Decoder.buffer.run(<Buffer 68 65 6c 6c 6f>) // OK
A decoder for dates. Decoding UTC time that is formatted using
toUTCString()
is not supported; Javascript's date parser parses UTC strings
wrong.
Example:
Decoder.date.run(123) // OK (Timestamp)
Decoder.date.run(new Date()) // OK
Decoder.date.run("abra") // FAIL
Decoder.date.run("2020-01-13T18:27:35.817Z") // OK
Decoder.date.run("Mon, 13 Jan 2020 18:28:05 GMT") // FAIL, format is not supported
A decoder for iso dates. Use Decoder.date
to also support timestamps.
Example:
Decoder.isoDate.run(new Date()) // OK
Decoder.isoDate.run("abra") // FAIL
Decoder.isoDate.run("2020-01-13T18:27:35.817Z") // OK
Decoder.isoDate.run(123) // FAIL
Decoder.isoDate.run("Mon, 13 Jan 2020 18:28:05 GMT") // FAIL, format is not supported
A decoder that accepts null.
Example:
Decoder.null.run(undefined) // FAIL
Decoder.null.run(5) // FAIL
Decoder.null.run(null) // OK
A decoder for numbers.
Example:
Decoder.number.run(5) // OK
Decoder.number.run('5') // OK
Decoder.number.run('hi') // FAIL
Decodes a string.
Example:
Decoder.string.run('hi') // OK
Decoder.string.run(5) // Fail
A decoder for timestamps.
Example:
Decoder.timestamp.run(123) // OK (Timestamp)
Decoder.timestamp.run(new Date()) // FAIL
Decoder.timestamp.run("abra") // FAIL
Decoder.timestamp.run("2020-01-13T18:27:35.817Z") // FAIL
Decoder.timestamp.run("Mon, 13 Jan 2020 18:28:05 GMT") // FAIL
A decoder that accepts undefined.
Example:
Decoder.undefined.run(null) // FAIL
Decoder.undefined.run(5) // FAIL
Decoder.undefined.run(undefined) // OK
Sets a default value to the decoder if it fails.
const nrDecoder = Decoder.number.default(0)
nrDecoder.run(5) // OK 5
nrDecoder.run('hi') // OK 0
Run a decoder on data. It will either succeed and yield the value or throw an ValidationFailed error
Transform a decoder from T to S.
Example:
const setDecoder: Decoder<Set<number>> =
Decoder.array(Decoder.number).map(numberArray => new Set(numberArray))
Run a decoder on data. The result is a discriminated union. *
Example:
const userCredentials: Decoder<Credentials> = Decoder.object({...})
//... Somewhere else
const result = userCredentials.run(request.query)
switch(result.type) {
case "OK":
login(result.value)
case "FAIL":
throw new Error(result.error)
}
Add an extra predicate to the decoder. Optionally add a failure message that overrides the earlier failure message.
Example:
const naturalNumber = Decoder.number.satisfy({
predicate: n => n>0
failureMessage: `Not a natural number`
})
naturalNumber.run(5) // OK, 5
naturalNumber.run(-1) // FAIL, Not a natural number
run a decoder on each item in an array, collecting the amount of successful and failed decodings.
example:
Decoder.number.sequence([1,3,4,"hello"]) // => {successful: [1,2,3], failed: ["hello"]}
Create decoders that is dependent on previous results.
Example:
const version = Decoder.field('version, Decoder.number)
const api = ({ version }: { version: number }): Decoder<{...}> => {
switch (version) {
case 0:
return myFirstDecoder;
case 1:
return mySecondDecoder;
default:
return Decoder.fail('Version ${version} not supported')
}
};
const versionedApi = version.then(api);
Decode values of an object where the keys are unknown.
Example:
const userDecoder = Decoder.object({age: Decoder.number})
const usersDecoder = Decoder.dict(userDecoder)
usersDecoder.run({emelie: {age: 32}, bob: {age: 50}}) // OK, {emelie: {age: 32}, bob: {age: 50}}
usersDecoder.run({name: 'emelie', age: 32}) // fail
Create a decoder that always fails with a message.
Decode the value of a specific key in an object using a given decoder.
Example:
const versionDecoder = Decoder.field("version", Decoder.number)
versionDecoder.run({version: 5}) // OK, 5
versionDecoder.run({name: "hi"}) // fail
Decodes the exact number and sets it to a number literal type.
Example:
const versionDecoder: Decoder<1 | 2> = Decoder.oneOf([
Decoder.literalNumber(1),
Decoder.literalNumber(2)
])
versionDecoder.run(1) // OK
versionDecoder.run(3) // FAIL
Decodes the exact string and sets it to a string literal type. Useful for parsing unions.
Example:
const jackOrSofia: Decoder<'Jack' | 'Sofia'> = Decoder.oneOf([
Decoder.literalString('Jack'),
Decoder.literalString('Sofia')
])
jackOrSofia.run('Jack') // OK
jackOrSofia.run('Josephine') // FAIL
Create a decoder for a type T.
Argument "object" is a Mapped type, an object containing only decoders for each field.
{name: Decoder.string} // Ok parameter
{name: Decoder.string, email: 'email@email'} // Type error, email must be decoder
Example:
interface User {
name: string
email: string
}
// typechecks
const decodeUser: Decoder<User> = Decoder.object({name: Decoder.string, email: Decoder.email})
decodeUser.run({name: "Jenny", email: "fakemail@fake.com"}) // OK
decodeUser.run({nm: "Bad"}) // FAIL
// will not typecheck, object must have the same field names as user and
// only contain decoders.
const decodeUser: Decoder<User> = Decoder.object({nem: 'Hi'})
Create a decoder that always suceeds and returns T.
Attempt multiple decoders in order until one succeeds. The type signature is informally:
oneOf = (decoders: [Decoder<A>, Decoder<B>, ...]) => Decoder<A | B | ...>
Example:
const enums: Decoder<"Jack" | "Sofia"> = Decoder.oneOf([
Decoder.literalString("Jack"),
Decoder.literalString("Sofia")
])
enums.run("Jack") // OK
enums.run("Sofia") // OK
enums.run("Josefine") // Fail
Takes a decoder and returns an optional decoder.
Example:
const optionalNumber = Decoder.optional(Decoder.number)
optionalNumber.run(5) //OK
optionalNumber.run(undefined) //OK
optionalNumber.run(null) //OK
optionalNumber.run('hi') //FAIL
Generated using TypeDoc
Decode data and check it's validity using Decoder. Useful when you want to check that data from clients or other outgoing sources is valid.
To create a decoder, use one of the primitive decoders provided as a static method. Then call it's deocde method on the data you want to decode.
const idDecoder<{id: string}> = Decoder.object({id: Decoder.string}) idDecoder.run("2913088") // Failure, must have a field id. const result = idDecoder.run({id: 2913088}) // OK // To access the result value switch(result.type) { case "OK": doThingWithId(result.value) case "FAIL": // Or if it fails you can find the reason by accessing error throw new Error(result.error) }