Skip to content

Latest commit

 

History

History
1271 lines (870 loc) · 36.6 KB

File metadata and controls

1271 lines (870 loc) · 36.6 KB

@mojotech/json-type-validation > "decoder" > Decoder

Class: Decoder

Decoders transform json objects with unknown structure into known and verified forms. You can create objects of type Decoder<A> with either the primitive decoder functions, such as boolean() and string(), or by applying higher-order decoders to the primitives, such as array(boolean()) or dict(string()).

Each of the decoder functions are available both as a static method on Decoder and as a function alias -- for example the string decoder is defined at Decoder.string(), but is also aliased to string(). Using the function aliases exported with the library is recommended.

Decoder exposes a number of 'run' methods, which all decode json in the same way, but communicate success and failure in different ways. The map and andThen methods modify decoders without having to call a 'run' method.

Alternatively, the main decoder run() method returns an object of type Result<A, DecoderError>. This library provides a number of helper functions for dealing with the Result type, so you can do all the same things with a Result as with the decoder methods.

Type parameters

A

Hierarchy

Decoder

Index

Constructors

Properties

Methods


Constructors

<Private> constructor

new Decoder(decode: function): Decoder

The Decoder class constructor is kept private to separate the internal decode function from the external run function. The distinction between the two functions is that decode returns a Partial<DecoderError> on failure, which contains an unfinished error report. When run is called on a decoder, the relevant series of decode calls is made, and then on failure the resulting Partial<DecoderError> is turned into a DecoderError by filling in the missing information.

While hiding the constructor may seem restrictive, leveraging the provided decoder combinators and helper functions such as andThen and map should be enough to build specialized decoders as needed.

Parameters:

Param Type
decode function

Returns: Decoder


Properties

<Private> decode

● decode: function

Type declaration

▸(json: unknown): DecodeResult<A>

Parameters:

Param Type
json unknown

Returns: DecodeResult<A>


Methods

andThen

andThenB(f: function): Decoder<B>

Chain together a sequence of decoders. The first decoder will run, and then the function will determine what decoder to run second. If the result of the first decoder succeeds then f will be applied to the decoded value. If it fails the error will propagate through.

This is a very powerful method -- it can act as both the map and where methods, can improve error messages for edge cases, and can be used to make a decoder for custom types.

Example of adding an error message:

const versionDecoder = valueAt(['version'], number());
const infoDecoder3 = object({a: boolean()});

const decoder = versionDecoder.andThen(version => {
  switch (version) {
    case 3:
      return infoDecoder3;
    default:
      return fail(`Unable to decode info, version ${version} is not supported.`);
  }
});

decoder.run({version: 3, a: true})
// => {ok: true, result: {a: true}}

decoder.run({version: 5, x: 'abc'})
// =>
// {
//   ok: false,
//   error: {... message: 'Unable to decode info, version 5 is not supported.'}
// }

Example of decoding a custom type:

// nominal type for arrays with a length of at least one
type NonEmptyArray<T> = T[] & { __nonEmptyArrayBrand__: void };

const nonEmptyArrayDecoder = <T>(values: Decoder<T>): Decoder<NonEmptyArray<T>> =>
  array(values).andThen(arr =>
    arr.length > 0
      ? succeed(createNonEmptyArray(arr))
      : fail(`expected a non-empty array, got an empty array`)
  );

Type parameters:

B

Parameters:

Param Type
f function

Returns: Decoder<B>


map

mapB(f: function): Decoder<B>

Construct a new decoder that applies a transformation to the decoded result. If the decoder succeeds then f will be applied to the value. If it fails the error will propagated through.

Example:

number().map(x => x * 5).run(10)
// => {ok: true, result: 50}

Type parameters:

B

Parameters:

Param Type
f function

Returns: Decoder<B>


run

run(json: unknown): RunResult<A>

Run the decoder and return a Result with either the decoded value or a DecoderError containing the json input, the location of the error, and the error message.

Examples:

number().run(12)
// => {ok: true, result: 12}

string().run(9001)
// =>
// {
//   ok: false,
//   error: {
//     kind: 'DecoderError',
//     input: 9001,
//     at: 'input',
//     message: 'expected a string, got 9001'
//   }
// }

Parameters:

Param Type
json unknown

Returns: RunResult<A>


runPromise

runPromise(json: unknown): Promise<A>

Run the decoder as a Promise.

Parameters:

Param Type
json unknown

Returns: Promise<A>


runWithException

runWithException(json: unknown): A

Run the decoder and return the value on success, or throw an exception with a formatted error string.

Parameters:

Param Type
json unknown

Returns: A


where

where(test: function, errorMessage: string): Decoder<A>

Add constraints to a decoder without changing the resulting type. The test argument is a predicate function which returns true for valid inputs. When test fails on an input, the decoder fails with the given errorMessage.

const chars = (length: number): Decoder<string> =>
  string().where(
    (s: string) => s.length === length,
    `expected a string of length ${length}`
  );

chars(5).run('12345')
// => {ok: true, result: '12345'}

chars(2).run('HELLO')
// => {ok: false, error: {... message: 'expected a string of length 2'}}

chars(12).run(true)
// => {ok: false, error: {... message: 'expected a string, got a boolean'}}

Parameters:

Param Type
test function
errorMessage string

Returns: Decoder<A>


<Static> anyJson

anyJson(): Decoder<any>

Escape hatch to bypass validation. Always succeeds and types the result as any. Useful for defining decoders incrementally, particularly for complex objects.

Example:

interface User {
  name: string;
  complexUserData: ComplexType;
}

const userDecoder: Decoder<User> = object({
  name: string(),
  complexUserData: anyJson()
});

Returns: Decoder<any>


<Static> array

array(): Decoder<unknown[]>

arrayA(decoder: Decoder<A>): Decoder<A[]>

Decoder for json arrays. Runs decoder on each array element, and succeeds if all elements are successfully decoded. If no decoder argument is provided then the outer array part of the json is validated but not the contents, typing the result as unknown[].

To decode a single value that is inside of an array see valueAt.

Examples:

array(number()).run([1, 2, 3])
// => {ok: true, result: [1, 2, 3]}

array(array(boolean())).run([[true], [], [true, false, false]])
// => {ok: true, result: [[true], [], [true, false, false]]}

const validNumbersDecoder = array()
  .map((arr: unknown[]) => arr.map(number().run))
  .map(Result.successes)

validNumbersDecoder.run([1, true, 2, 3, 'five', 4, []])
// {ok: true, result: [1, 2, 3, 4]}

validNumbersDecoder.run([false, 'hi', {}])
// {ok: true, result: []}

validNumbersDecoder.run(false)
// {ok: false, error: {..., message: "expected an array, got a boolean"}}

Returns: Decoder<unknown[]>

Type parameters:

A

Parameters:

Param Type
decoder Decoder<A>

Returns: Decoder<A[]>


<Static> boolean

boolean(): Decoder<boolean>

Decoder primitive that validates booleans, and fails on all other input.

Returns: Decoder<boolean>


<Static> constant

constant(value: true): Decoder<true>

constant(value: false): Decoder<false>

constantA(value: A): Decoder<A>

Decoder primitive that only matches on exact values.

Note that constant('string to match') returns a Decoder<string> which fails if the input is not equal to 'string to match'. In many cases this is sufficient, but in some situations typescript requires that the decoder type be a type-literal. In such a case you must provide the type parameter, which looks like constant<'string to match'>('string to match').

Providing the type parameter is only necessary for type-literal strings and numbers, as detailed by this table:

| Decoder                      | Type                 |
 | ---------------------------- | ---------------------|
 | constant(true)               | Decoder<true>        |
 | constant(false)              | Decoder<false>       |
 | constant(null)               | Decoder<null>        |
 | constant('alaska')           | Decoder<string>      |
 | constant<'alaska'>('alaska') | Decoder<'alaska'>    |
 | constant(50)                 | Decoder<number>      |
 | constant<50>(50)             | Decoder<50>          |
 | constant([1,2,3])            | Decoder<number[]>    |
 | constant<[1,2,3]>([1,2,3])   | Decoder<[1,2,3]>     |
 | constant({x: 't'})           | Decoder<{x: string}> |
 | constant<{x: 't'}>({x: 't'}) | Decoder<{x: 't'}>    |

One place where this happens is when a type-literal is in an interface:

interface Bear {
  kind: 'bear';
  isBig: boolean;
}

const bearDecoder1: Decoder<Bear> = object({
  kind: constant('bear'),
  isBig: boolean()
});
// Type 'Decoder<{ kind: string; isBig: boolean; }>' is not assignable to
// type 'Decoder<Bear>'. Type 'string' is not assignable to type '"bear"'.

const bearDecoder2: Decoder<Bear> = object({
  kind: constant<'bear'>('bear'),
  isBig: boolean()
});
// no compiler errors

Another is in type-literal unions:

type animal = 'bird' | 'bear';

const animalDecoder1: Decoder<animal> = union(
  constant('bird'),
  constant('bear')
);
// Type 'Decoder<string>' is not assignable to type 'Decoder<animal>'.
// Type 'string' is not assignable to type 'animal'.

const animalDecoder2: Decoder<animal> = union(
  constant<'bird'>('bird'),
  constant<'bear'>('bear')
);
// no compiler errors

Parameters:

Param Type
value true

Returns: Decoder<true>

Parameters:

Param Type
value false

Returns: Decoder<false>

Type parameters:

A

Parameters:

Param Type
value A

Returns: Decoder<A>


<Static> dict

dictA(decoder: Decoder<A>): Decoder<Record<string, A>>

Decoder for json objects where the keys are unknown strings, but the values should all be of the same type.

Example:

dict(number()).run({chocolate: 12, vanilla: 10, mint: 37});
// => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}}

Type parameters:

A

Parameters:

Param Type
decoder Decoder<A>

Returns: Decoder<Record<string, A>>


<Static> fail

failA(errorMessage: string): Decoder<A>

Decoder that ignores the input json and always fails with errorMessage.

Type parameters:

A

Parameters:

Param Type
errorMessage string

Returns: Decoder<A>


<Static> intersection

intersectionA,B(ad: Decoder<A>, bd: Decoder<B>): Decoder< A & B>

intersectionA,B,C(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>): Decoder< A & B & C>

intersectionA,B,C,D(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>): Decoder< A & B & C & D>

intersectionA,B,C,D,E(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>, ed: Decoder<E>): Decoder< A & B & C & D & E>

intersectionA,B,C,D,E,F(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>, ed: Decoder<E>, fd: Decoder<F>): Decoder< A & B & C & D & E & F>

intersectionA,B,C,D,E,F,G(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>, ed: Decoder<E>, fd: Decoder<F>, gd: Decoder<G>): Decoder< A & B & C & D & E & F & G>

intersectionA,B,C,D,E,F,G,H(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>, ed: Decoder<E>, fd: Decoder<F>, gd: Decoder<G>, hd: Decoder<H>): Decoder< A & B & C & D & E & F & G & H>

Combines 2-8 object decoders into a decoder for the intersection of all the objects.

Example:

interface Pet {
  name: string;
  maxLegs: number;
}

interface Cat extends Pet {
  evil: boolean;
}

const petDecoder: Decoder<Pet> = object({name: string(), maxLegs: number()});
const catDecoder: Decoder<Cat> = intersection(petDecoder, object({evil: boolean()}));

Type parameters:

A

B

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>

Returns: Decoder< A & B>

Type parameters:

A

B

C

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>

Returns: Decoder< A & B & C>

Type parameters:

A

B

C

D

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>

Returns: Decoder< A & B & C & D>

Type parameters:

A

B

C

D

E

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>
ed Decoder<E>

Returns: Decoder< A & B & C & D & E>

Type parameters:

A

B

C

D

E

F

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>
ed Decoder<E>
fd Decoder<F>

Returns: Decoder< A & B & C & D & E & F>

Type parameters:

A

B

C

D

E

F

G

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>
ed Decoder<E>
fd Decoder<F>
gd Decoder<G>

Returns: Decoder< A & B & C & D & E & F & G>

Type parameters:

A

B

C

D

E

F

G

H

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>
ed Decoder<E>
fd Decoder<F>
gd Decoder<G>
hd Decoder<H>

Returns: Decoder< A & B & C & D & E & F & G & H>


<Static> lazy

lazyA(mkDecoder: function): Decoder<A>

Decoder that allows for validating recursive data structures. Unlike with functions, decoders assigned to variables can't reference themselves before they are fully defined. We can avoid prematurely referencing the decoder by wrapping it in a function that won't be called until use, at which point the decoder has been defined.

Example:

interface Comment {
  msg: string;
  replies: Comment[];
}

const decoder: Decoder<Comment> = object({
  msg: string(),
  replies: lazy(() => array(decoder))
});

Type parameters:

A

Parameters:

Param Type
mkDecoder function

Returns: Decoder<A>


<Static> number

number(): Decoder<number>

Decoder primitive that validates numbers, and fails on all other input.

Returns: Decoder<number>


<Static> object

object(): Decoder<Record<string, unknown>>

objectA(decoders: DecoderObject<A>): Decoder<A>

An higher-order decoder that runs decoders on specified fields of an object, and returns a new object with those fields. If object is called with no arguments, then the outer object part of the json is validated but not the contents, typing the result as a record where all keys have a value of type unknown.

The optional and constant decoders are particularly useful for decoding objects that match typescript interfaces.

To decode a single field that is inside of an object see valueAt.

Example:

object({x: number(), y: number()}).run({x: 5, y: 10})
// => {ok: true, result: {x: 5, y: 10}}

object().map(Object.keys).run({n: 1, i: [], c: {}, e: 'e'})
// => {ok: true, result: ['n', 'i', 'c', 'e']}

Returns: Decoder<Record<string, unknown>>

Type parameters:

A

Parameters:

Param Type
decoders DecoderObject<A>

Returns: Decoder<A>


<Static> oneOf

oneOfA(...decoders: Decoder<A>[]): Decoder<A>

Decoder that attempts to run each decoder in decoders and either succeeds with the first successful decoder, or fails after all decoders have failed.

Note that oneOf expects the decoders to all have the same return type, while union creates a decoder for the union type of all the input decoders.

Examples:

oneOf(string(), number().map(String))
oneOf(constant('start'), constant('stop'), succeed('unknown'))

Type parameters:

A

Parameters:

Param Type
Rest decoders Decoder<A>[]

Returns: Decoder<A>


<Static> optional

optionalA(decoder: Decoder<A>): Decoder< undefined | A>

Decoder for values that may be undefined. This is primarily helpful for decoding interfaces with optional fields.

Example:

interface User {
  id: number;
  isOwner?: boolean;
}

const decoder: Decoder<User> = object({
  id: number(),
  isOwner: optional(boolean())
});

Type parameters:

A

Parameters:

Param Type
decoder Decoder<A>

Returns: Decoder< undefined | A>


<Static> string

string(): Decoder<string>

Decoder primitive that validates strings, and fails on all other input.

Returns: Decoder<string>


<Static> succeed

succeedA(fixedValue: A): Decoder<A>

Decoder that ignores the input json and always succeeds with fixedValue.

Type parameters:

A

Parameters:

Param Type
fixedValue A

Returns: Decoder<A>


<Static> tuple

tupleA(decoder: [Decoder<A>]): Decoder<[A]>

tupleA,B(decoder: [Decoder<A>, Decoder<B>]): Decoder<[A, B]>

tupleA,B,C(decoder: [Decoder<A>, Decoder<B>, Decoder<C>]): Decoder<[A, B, C]>

tupleA,B,C,D(decoder: [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>]): Decoder<[A, B, C, D]>

tupleA,B,C,D,E(decoder: [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>, Decoder<E>]): Decoder<[A, B, C, D, E]>

tupleA,B,C,D,E,F(decoder: [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>, Decoder<E>, Decoder<F>]): Decoder<[A, B, C, D, E, F]>

tupleA,B,C,D,E,F,G(decoder: [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>, Decoder<E>, Decoder<F>, Decoder<G>]): Decoder<[A, B, C, D, E, F, G]>

tupleA,B,C,D,E,F,G,H(decoder: [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>, Decoder<E>, Decoder<F>, Decoder<G>, Decoder<H>]): Decoder<[A, B, C, D, E, F, G, H]>

Decoder for fixed-length arrays, aka Tuples.

Supports up to 8-tuples.

Example:

tuple([number(), number(), string()]).run([5, 10, 'px'])
// => {ok: true, result: [5, 10, 'px']}

Type parameters:

A

Parameters:

Param Type
decoder [Decoder<A>]

Returns: Decoder<[A]>

Type parameters:

A

B

Parameters:

Param Type
decoder [Decoder<A>, Decoder<B>]

Returns: Decoder<[A, B]>

Type parameters:

A

B

C

Parameters:

Param Type
decoder [Decoder<A>, Decoder<B>, Decoder<C>]

Returns: Decoder<[A, B, C]>

Type parameters:

A

B

C

D

Parameters:

Param Type
decoder [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>]

Returns: Decoder<[A, B, C, D]>

Type parameters:

A

B

C

D

E

Parameters:

Param Type
decoder [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>, Decoder<E>]

Returns: Decoder<[A, B, C, D, E]>

Type parameters:

A

B

C

D

E

F

Parameters:

Param Type
decoder [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>, Decoder<E>, Decoder<F>]

Returns: Decoder<[A, B, C, D, E, F]>

Type parameters:

A

B

C

D

E

F

G

Parameters:

Param Type
decoder [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>, Decoder<E>, Decoder<F>, Decoder<G>]

Returns: Decoder<[A, B, C, D, E, F, G]>

Type parameters:

A

B

C

D

E

F

G

H

Parameters:

Param Type
decoder [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>, Decoder<E>, Decoder<F>, Decoder<G>, Decoder<H>]

Returns: Decoder<[A, B, C, D, E, F, G, H]>


<Static> union

unionA,B(ad: Decoder<A>, bd: Decoder<B>): Decoder< A | B>

unionA,B,C(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>): Decoder< A | B | C>

unionA,B,C,D(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>): Decoder< A | B | C | D>

unionA,B,C,D,E(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>, ed: Decoder<E>): Decoder< A | B | C | D | E>

unionA,B,C,D,E,F(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>, ed: Decoder<E>, fd: Decoder<F>): Decoder< A | B | C | D | E | F>

unionA,B,C,D,E,F,G(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>, ed: Decoder<E>, fd: Decoder<F>, gd: Decoder<G>): Decoder< A | B | C | D | E | F | G>

unionA,B,C,D,E,F,G,H(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>, ed: Decoder<E>, fd: Decoder<F>, gd: Decoder<G>, hd: Decoder<H>): Decoder< A | B | C | D | E | F | G | H>

Combines 2-8 decoders of disparate types into a decoder for the union of all the types.

If you need more than 8 variants for your union, it's possible to use oneOf in place of union as long as you annotate every decoder with the union type.

Example:

type C = {a: string} | {b: number};

const unionDecoder: Decoder<C> = union(object({a: string()}), object({b: number()}));
const oneOfDecoder: Decoder<C> = oneOf(object<C>({a: string()}), object<C>({b: number()}));

Type parameters:

A

B

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>

Returns: Decoder< A | B>

Type parameters:

A

B

C

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>

Returns: Decoder< A | B | C>

Type parameters:

A

B

C

D

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>

Returns: Decoder< A | B | C | D>

Type parameters:

A

B

C

D

E

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>
ed Decoder<E>

Returns: Decoder< A | B | C | D | E>

Type parameters:

A

B

C

D

E

F

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>
ed Decoder<E>
fd Decoder<F>

Returns: Decoder< A | B | C | D | E | F>

Type parameters:

A

B

C

D

E

F

G

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>
ed Decoder<E>
fd Decoder<F>
gd Decoder<G>

Returns: Decoder< A | B | C | D | E | F | G>

Type parameters:

A

B

C

D

E

F

G

H

Parameters:

Param Type
ad Decoder<A>
bd Decoder<B>
cd Decoder<C>
dd Decoder<D>
ed Decoder<E>
fd Decoder<F>
gd Decoder<G>
hd Decoder<H>

Returns: Decoder< A | B | C | D | E | F | G | H>


<Static> unknownJson

unknownJson(): Decoder<unknown>

Decoder identity function which always succeeds and types the result as unknown.

Returns: Decoder<unknown>


<Static> valueAt

valueAtA(paths: ( string | number)[], decoder: Decoder<A>): Decoder<A>

Decoder that pulls a specific field out of a json structure, instead of decoding and returning the full structure. The paths array describes the object keys and array indices to traverse, so that values can be pulled out of a nested structure.

Example:

const decoder = valueAt(['a', 'b', 0], string());

decoder.run({a: {b: ['surprise!']}})
// => {ok: true, result: 'surprise!'}

decoder.run({a: {x: 'cats'}})
// => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}}

Note that the decoder is ran on the value found at the last key in the path, even if the last key is not found. This allows the optional decoder to succeed when appropriate.

const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string()));

optionalDecoder.run({a: {b: {c: 'surprise!'}}})
// => {ok: true, result: 'surprise!'}

optionalDecoder.run({a: {b: 'cats'}})
// => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got "cats"'}

optionalDecoder.run({a: {b: {z: 1}}})
// => {ok: true, result: undefined}

Type parameters:

A

Parameters:

Param Type
paths ( string | number)[]
decoder Decoder<A>

Returns: Decoder<A>


<Static> withDefault

withDefaultA(defaultValue: A, decoder: Decoder<A>): Decoder<A>

Decoder that always succeeds with either the decoded value, or a fallback default value.

Type parameters:

A

Parameters:

Param Type
defaultValue A
decoder Decoder<A>

Returns: Decoder<A>