@@ -618,10 +618,13 @@ export class Decoder<A> {
618618 * Chain together a sequence of decoders. The first decoder will run, and
619619 * then the function will determine what decoder to run second. If the result
620620 * of the first decoder succeeds then `f` will be applied to the decoded
621- * value. If it fails the error will propagate through. One use case for
622- * `andThen` is returning a custom error message.
621+ * value. If it fails the error will propagate through.
623622 *
624- * Example:
623+ * This is a very powerful method -- it can act as both the `map` and `where`
624+ * methods, can improve error messages for edge cases, and can be used to
625+ * make a decoder for custom types.
626+ *
627+ * Example of adding an error message:
625628 * ```
626629 * const versionDecoder = valueAt(['version'], number());
627630 * const infoDecoder3 = object({a: boolean()});
@@ -642,13 +645,22 @@ export class Decoder<A> {
642645 * // =>
643646 * // {
644647 * // ok: false,
645- * // error: {
646- * // ...
647- * // at: 'input',
648- * // message: 'Unable to decode info, version 5 is not supported.'
649- * // }
648+ * // error: {... message: 'Unable to decode info, version 5 is not supported.'}
650649 * // }
651650 * ```
651+ *
652+ * Example of decoding a custom type:
653+ * ```
654+ * // nominal type for arrays with a length of at least one
655+ * type NonEmptyArray<T> = T[] & { __nonEmptyArrayBrand__: void };
656+ *
657+ * const nonEmptyArrayDecoder = <T>(values: Decoder<T>): Decoder<NonEmptyArray<T>> =>
658+ * array(values).andThen(arr =>
659+ * arr.length > 0
660+ * ? succeed(createNonEmptyArray(arr))
661+ * : fail(`expected a non-empty array, got an empty array`)
662+ * );
663+ * ```
652664 */
653665 andThen = < B > ( f : ( value : A ) => Decoder < B > ) : Decoder < B > =>
654666 new Decoder < B > ( ( json : any ) =>
0 commit comments