[
  {
    "path": ".gitignore",
    "content": "node_modules\ncoverage\n.nyc_output\n.DS_Store\n*.log\n.vscode\n.idea\ndist\ncompiled\n.awcache\n.rpt2_cache\ngc-roots\n"
  },
  {
    "path": ".npmignore",
    "content": ".git/\n.rpt2_cache/\nbin/\ncoverage/\nnix-files/\nnode_modules/\nsrc/\ntest/\n.gitignore\n.prettierrc\n.travis.yml\nrollup.config.ts\ntags\ntsconfig-test.json\ntsconfig.json\ntslint.json\nyarn.lock\n"
  },
  {
    "path": ".prettierignore",
    "content": "package.json\ndist/\n"
  },
  {
    "path": ".prettierrc",
    "content": "printWidth: 100\ntabWidth: 2\nuseTabs: false\nsemi: true\nsingleQuote: true\ntrailingComma: none\nbracketSpacing: false\narrowParens: avoid\nparser: typescript\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\ncache:\n  yarn: true\n  directories:\n    - node_modules\nnotifications:\n  email: false\nnode_js:\n  - node\nscript:\n  - npm run test:prod && npm run build\nafter_success:\n  - npm run report-coverage\n"
  },
  {
    "path": "DOCS.md",
    "content": "# Documentation\n\n[Documentation](https://github.com/mojotech/json-type-validation/tree/master/docs).\n\nThe best places to start are with the examples in the `test/` directory, and the\ndocumentation for the\n[Decoder class](https://github.com/mojotech/json-type-validation/blob/master/docs/classes/_decoder_.decoder.md).\nAt some point you may need documentation for dealing with the\n[Result type](https://github.com/mojotech/json-type-validation/blob/master/docs/modules/_result_.md).\n\n### Type Parameters\n\nMany of the decoder functions take an optional type parameter which determines\nthe type of the decoded value. In most cases typescript successfully infers\nthese types, although some specific decoders include documentation for\nsituations where the type is necessary (see the `constant` and `union`\ndecoders). You may still find that including the type parameter improves type\ninference in situations where typescript's error messages are particularly\nunhelpful.\n\nAs an example, a decoder for the `Pet` interface can be typechecked just as\neffectively using the type parameter as with the `Decoder<Pet>` annotation.\n```\nconst petDecoder = object<Pet>({\n  name: string(),\n  species: string(),\n  age: optional(number()),\n  isCute: optional(boolean())\n})\n```\n\n### Combinators\n\nThis library uses the [combinator pattern](https://wiki.haskell.org/Combinator_pattern)\nto build decoders. The decoder primitives `string`, `number`, `boolean`,\n`anyJson`, `constant`, `succeed`, and `fail` act as decoder building blocks that\neach perform a simple decoding operation. The decoder combinators `object`,\n`array`, `dict`, `optional`, `oneOf`, `union`, `withDefault`, `valueAt`, and\n`lazy` take decoders as arguments, and combined the decoders into more\ncomplicated structures. You can think of your own user-defined decoders as an\nextension of these composable units.\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2018 Elias Mulhall\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# JSON Type Validation\n\nA [TypeScript](https://www.typescriptlang.org/) library to perform type checking and validation on untyped JSON data at runtime.\n\nThis library owes thanks to:\n\n- [JsonDecoder](https://github.com/aische/JsonDecoder) by Daniel van den Eijkel\n- [Type-safe JSON Decoder](https://github.com/ooesili/type-safe-json-decoder) by Wesley Merkel\n- The Elm [Json.Decode](http://package.elm-lang.org/packages/elm-lang/core/latest/Json-Decode) API\n\n## Installation\n```\nnpm i @mojotech/json-type-validation\n```\nProjects using `< typescript@3.0.1` will need a polyfill for the `unknown`\ntype, such as [unknown-ts](https://www.npmjs.com/package/unknown-ts).\n\n## Motivation\n\nLet's say we're creating a web app for our pet sitting business, and we've\npicked TypeScript as one of our core technologies. This is a great choice\nbecause the extra stability and type safety that TypeScript provides is really\ngoing to help us market our business.\n\nWe've defined the data we need to track about each client's pet:\n\n```typescript\ninterface Pet {\n  name: string;\n  species: string;\n  age?: number;\n  isCute?: boolean;\n}\n```\n\nAnd we've got some data about current client's pets which is stored as JSON:\n\n```typescript\nconst croc: Pet = JSON.parse('{\"name\":\"Lyle\",\"species\":\"Crocodile\",\"isCute\":true}')\nconst moose: Pet = JSON.parse('{\"name\":\"Bullwinkle\",\"age\":59}')\n```\n\nBut that can't be right -- our data for `moose` is missing information required\nfor the `Pet` interface, but TypeScript compiles the code just fine!\n\nOf course this isn't an issue with TypeScript, but with our own type\nannotations. In TypeScript `JSON.parse` has a return type of `any`, which pushes\nthe responsibility of verifying the type of data onto the user. By assuming that\nall of our data is correctly formed, we've left ourselves open to unexpected\nerrors at runtime.\n\nUnfortunately TypeScript doesn't provide a good built-in way to deal with this\nissue. Providing run-time type information is one of TypeScript's\n[non-goals](https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals#non-goals),\nand our web app is too important to risk using a forked version of TypeScript\nwith that added functionality.\n[Type guards](https://basarat.gitbooks.io/typescript/docs/types/typeGuard.html)\nwork, but are limited in that they circumvent type inference instead of working\nwith it, and can be cumbersome to write.\n\nWith `json-type-validation` we can define decoders that validate untyped json\ninput. Decoders are concise, composable, and typecheck against our defined types\nand interfaces.\n\n```typescript\nimport {Decoder, object, string, optional, number, boolean} from '@mojotech/json-type-validation'\n\nconst petDecoder: Decoder<Pet> = object({\n  name: string(),\n  species: string(),\n  age: optional(number()),\n  isCute: optional(boolean())\n})\n```\n\nFinally, we can choose from a number of decoding methods to validate json and\nreport success or failure. When some json input fails validation the decoder\nclearly shows how the data was malformed.\n\n```typescript\nconst lyle: Pet = petDecoder.runWithException(croc)\n\nconst bullwinkle: Pet = petDecoder.runWithException(moose)\n// Throws the exception:\n// `Input: {\"name\":\"Bullwinkle\",\"age\":59}\n//  Failed at input: the key 'species' is required but was not present`\n```\n\n## Documentation\n\n[Documentation](https://github.com/mojotech/json-type-validation/tree/master/docs).\n\n## Building\n\n### With Nix\n\nThere exists some [Nix](https://nixos.org/nix) infrastructure that can be used\nto reproduce a build environment exactly. A helper shell script lives at\n`bin/jtv` that you can use to enter environments for multiple uses.\nYou'll need to follow the directions on the Nix website to install and use the\nNix package manager.\n\n* To enter a shell suitable for building the library run `./bin/jtv\n  build-shell`. This will leave you in the root of the project and automatically\n  install any project and npm dependencies. You can run further yarn commands\n  here.\n* To build the library for distribution and exit you can run `./bin/jtv distribute`.\n* To enter a build shell and run the build process, watching for changes, run\n  `./bin/jtv build-watch`.\n* To run an arbitrary command in a build environment use `./bin/jtv run\n  COMMAND`. For example, `./bin/jtv run yarn test` will run the tests and exit.\n"
  },
  {
    "path": "bin/jtv",
    "content": "#!/usr/bin/env bash\n\nSCRIPTNAME=$(basename $0)\nDIRNAME=$(dirname $0)\nMODE=$1\n\nshift\n\nprint_help() {\n    echo \"Usage: $SCRIPTNAME MODE\"\n    echo \"Enter a shell with all dependencies required for MODE.\"\n    echo \"MODE is one of:\"\n    echo \"  build-shell - enter a shell for building the library\"\n    echo \"  build-watch - enter a build shell and run \\`yarn start\\`\"\n    echo \"  distribute - build the library and exist\"\n    echo \"  run COMMAND - enter a build shell and run the specified command\"\n    echo \"  help, --help, -h - display this help message\"\n}\nif [ \"$MODE\" = \"help\" -o \"$MODE\" = \"--help\" -o \"$MODE\" = \"-h\" ]; then\n    print_help\n    exit 0\nfi\n\nif [ \"$MODE\" = \"build-shell\" ]; then\n    echo \"Starting build shell...\"\n    # --add-root, --indirect place a garbage collection root outside of the main\n    # nix store directory. This allows you to run nix-collect-garbage without\n    # collecting the dependencies for this package. To collect the dependencies\n    # for this package, delete the roots in gc-roots.\n    # --pure limits the generated shell to only those dependencies specified in\n    # the nix file.\n    nix-shell --pure --add-root $DIRNAME/../gc-roots/json-type-validation.drv --indirect $DIRNAME/../nix-files/shell.nix\nelif [ \"$MODE\" = \"build-watch\" ]; then\n    echo \"Starting build watcher...\"\n    nix-shell --pure --add-root $DIRNAME/../gc-roots/json-type-validation.drv --indirect $DIRNAME/../nix-files/shell.nix --run \"yarn start\"\nelif [ \"$MODE\" = \"distribute\" ]; then\n    echo \"Building library for distribution...\"\n    nix-shell --pure --add-root $DIRNAME/../gc-roots/json-type-validation.drv --indirect $DIRNAME/../nix-files/shell.nix --run \"yarn build\"\n\nelif [ \"$MODE\" = \"run\" ]; then\n    echo \"Running \\`$@\\` in build environment...\"\n    nix-shell --pure --add-root $DIRNAME/../gc-roots/json-type-validation.drv --indirect $DIRNAME/../nix-files/shell.nix --run \"$*\"\nelse\n    echo \"Must specify MODE!\"\n    print_help\n    exit 1\nfi\n"
  },
  {
    "path": "docs/README.md",
    "content": "\nDocumentation\n=============\n\n[Documentation](https://github.com/mojotech/json-type-validation/tree/master/docs).\n\nThe best places to start are with the examples in the `test/` directory, and the documentation for the [Decoder class](https://github.com/mojotech/json-type-validation/blob/master/docs/classes/_decoder_.decoder.md). At some point you may need documentation for dealing with the [Result type](https://github.com/mojotech/json-type-validation/blob/master/docs/modules/_result_.md).\n\n### Type Parameters\n\nMany of the decoder functions take an optional type parameter which determines the type of the decoded value. In most cases typescript successfully infers these types, although some specific decoders include documentation for situations where the type is necessary (see the `constant` and `union` decoders). You may still find that including the type parameter improves type inference in situations where typescript's error messages are particularly unhelpful.\n\nAs an example, a decoder for the `Pet` interface can be typechecked just as effectively using the type parameter as with the `Decoder<Pet>` annotation.\n\n```\nconst petDecoder = object<Pet>({\n  name: string(),\n  species: string(),\n  age: optional(number()),\n  isCute: optional(boolean())\n})\n```\n\n### Combinators\n\nThis library uses the [combinator pattern](https://wiki.haskell.org/Combinator_pattern) to build decoders. The decoder primitives `string`, `number`, `boolean`, `anyJson`, `constant`, `succeed`, and `fail` act as decoder building blocks that each perform a simple decoding operation. The decoder combinators `object`, `array`, `dict`, `optional`, `oneOf`, `union`, `withDefault`, `valueAt`, and `lazy` take decoders as arguments, and combined the decoders into more complicated structures. You can think of your own user-defined decoders as an extension of these composable units.\n\n## Index\n\n### External modules\n\n* [\"combinators\"](modules/_combinators_.md)\n* [\"decoder\"](modules/_decoder_.md)\n* [\"index\"](modules/_index_.md)\n* [\"result\"](modules/_result_.md)\n\n---\n\n"
  },
  {
    "path": "docs/classes/_decoder_.decoder.md",
    "content": "[@mojotech/json-type-validation](../README.md) > [\"decoder\"](../modules/_decoder_.md) > [Decoder](../classes/_decoder_.decoder.md)\n\n# Class: Decoder\n\nDecoders 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())`.\n\nEach 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.\n\n`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.\n\nAlternatively, 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.\n\n## Type parameters\n#### A \n## Hierarchy\n\n**Decoder**\n\n## Index\n\n### Constructors\n\n* [constructor](_decoder_.decoder.md#constructor)\n\n### Properties\n\n* [decode](_decoder_.decoder.md#decode)\n\n### Methods\n\n* [andThen](_decoder_.decoder.md#andthen)\n* [map](_decoder_.decoder.md#map)\n* [run](_decoder_.decoder.md#run)\n* [runPromise](_decoder_.decoder.md#runpromise)\n* [runWithException](_decoder_.decoder.md#runwithexception)\n* [where](_decoder_.decoder.md#where)\n* [anyJson](_decoder_.decoder.md#anyjson)\n* [array](_decoder_.decoder.md#array)\n* [boolean](_decoder_.decoder.md#boolean)\n* [constant](_decoder_.decoder.md#constant)\n* [dict](_decoder_.decoder.md#dict)\n* [fail](_decoder_.decoder.md#fail)\n* [intersection](_decoder_.decoder.md#intersection)\n* [lazy](_decoder_.decoder.md#lazy)\n* [number](_decoder_.decoder.md#number)\n* [object](_decoder_.decoder.md#object)\n* [oneOf](_decoder_.decoder.md#oneof)\n* [optional](_decoder_.decoder.md#optional)\n* [string](_decoder_.decoder.md#string)\n* [succeed](_decoder_.decoder.md#succeed)\n* [tuple](_decoder_.decoder.md#tuple)\n* [union](_decoder_.decoder.md#union)\n* [unknownJson](_decoder_.decoder.md#unknownjson)\n* [valueAt](_decoder_.decoder.md#valueat)\n* [withDefault](_decoder_.decoder.md#withdefault)\n\n---\n\n## Constructors\n\n<a id=\"constructor\"></a>\n\n### `<Private>` constructor\n\n⊕ **new Decoder**(decode: *`function`*): [Decoder](_decoder_.decoder.md)\n\nThe 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.\n\nWhile 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.\n\n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decode | `function` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)\n\n___\n\n## Properties\n\n<a id=\"decode\"></a>\n\n### `<Private>` decode\n\n**● decode**: *`function`*\n\n#### Type declaration\n▸(json: *`unknown`*): `DecodeResult`<`A`>\n\n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| json | `unknown` |\n\n**Returns:** `DecodeResult`<`A`>\n\n___\n\n## Methods\n\n<a id=\"andthen\"></a>\n\n###  andThen\n\n▸ **andThen**B(f: *`function`*): [Decoder](_decoder_.decoder.md)<`B`>\n\nChain 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.\n\nThis 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.\n\nExample of adding an error message:\n\n```\nconst versionDecoder = valueAt(['version'], number());\nconst infoDecoder3 = object({a: boolean()});\n\nconst decoder = versionDecoder.andThen(version => {\n  switch (version) {\n    case 3:\n      return infoDecoder3;\n    default:\n      return fail(`Unable to decode info, version ${version} is not supported.`);\n  }\n});\n\ndecoder.run({version: 3, a: true})\n// => {ok: true, result: {a: true}}\n\ndecoder.run({version: 5, x: 'abc'})\n// =>\n// {\n//   ok: false,\n//   error: {... message: 'Unable to decode info, version 5 is not supported.'}\n// }\n```\n\nExample of decoding a custom type:\n\n```\n// nominal type for arrays with a length of at least one\ntype NonEmptyArray<T> = T[] & { __nonEmptyArrayBrand__: void };\n\nconst nonEmptyArrayDecoder = <T>(values: Decoder<T>): Decoder<NonEmptyArray<T>> =>\n  array(values).andThen(arr =>\n    arr.length > 0\n      ? succeed(createNonEmptyArray(arr))\n      : fail(`expected a non-empty array, got an empty array`)\n  );\n```\n\n**Type parameters:**\n\n#### B \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| f | `function` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`B`>\n\n___\n<a id=\"map\"></a>\n\n###  map\n\n▸ **map**B(f: *`function`*): [Decoder](_decoder_.decoder.md)<`B`>\n\nConstruct 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.\n\nExample:\n\n```\nnumber().map(x => x * 5).run(10)\n// => {ok: true, result: 50}\n```\n\n**Type parameters:**\n\n#### B \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| f | `function` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`B`>\n\n___\n<a id=\"run\"></a>\n\n###  run\n\n▸ **run**(json: *`unknown`*): `RunResult`<`A`>\n\nRun 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.\n\nExamples:\n\n```\nnumber().run(12)\n// => {ok: true, result: 12}\n\nstring().run(9001)\n// =>\n// {\n//   ok: false,\n//   error: {\n//     kind: 'DecoderError',\n//     input: 9001,\n//     at: 'input',\n//     message: 'expected a string, got 9001'\n//   }\n// }\n```\n\n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| json | `unknown` |\n\n**Returns:** `RunResult`<`A`>\n\n___\n<a id=\"runpromise\"></a>\n\n###  runPromise\n\n▸ **runPromise**(json: *`unknown`*): `Promise`<`A`>\n\nRun the decoder as a `Promise`.\n\n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| json | `unknown` |\n\n**Returns:** `Promise`<`A`>\n\n___\n<a id=\"runwithexception\"></a>\n\n###  runWithException\n\n▸ **runWithException**(json: *`unknown`*): `A`\n\nRun the decoder and return the value on success, or throw an exception with a formatted error string.\n\n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| json | `unknown` |\n\n**Returns:** `A`\n\n___\n<a id=\"where\"></a>\n\n###  where\n\n▸ **where**(test: *`function`*, errorMessage: *`string`*): [Decoder](_decoder_.decoder.md)<`A`>\n\nAdd 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`.\n\n```\nconst chars = (length: number): Decoder<string> =>\n  string().where(\n    (s: string) => s.length === length,\n    `expected a string of length ${length}`\n  );\n\nchars(5).run('12345')\n// => {ok: true, result: '12345'}\n\nchars(2).run('HELLO')\n// => {ok: false, error: {... message: 'expected a string of length 2'}}\n\nchars(12).run(true)\n// => {ok: false, error: {... message: 'expected a string, got a boolean'}}\n```\n\n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| test | `function` |\n| errorMessage | `string` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`>\n\n___\n<a id=\"anyjson\"></a>\n\n### `<Static>` anyJson\n\n▸ **anyJson**(): [Decoder](_decoder_.decoder.md)<`any`>\n\nEscape hatch to bypass validation. Always succeeds and types the result as `any`. Useful for defining decoders incrementally, particularly for complex objects.\n\nExample:\n\n```\ninterface User {\n  name: string;\n  complexUserData: ComplexType;\n}\n\nconst userDecoder: Decoder<User> = object({\n  name: string(),\n  complexUserData: anyJson()\n});\n```\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`any`>\n\n___\n<a id=\"array\"></a>\n\n### `<Static>` array\n\n▸ **array**(): [Decoder](_decoder_.decoder.md)<`unknown`[]>\n\n▸ **array**A(decoder: *[Decoder](_decoder_.decoder.md)<`A`>*): [Decoder](_decoder_.decoder.md)<`A`[]>\n\nDecoder 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[]`.\n\nTo decode a single value that is inside of an array see `valueAt`.\n\nExamples:\n\n```\narray(number()).run([1, 2, 3])\n// => {ok: true, result: [1, 2, 3]}\n\narray(array(boolean())).run([[true], [], [true, false, false]])\n// => {ok: true, result: [[true], [], [true, false, false]]}\n\nconst validNumbersDecoder = array()\n  .map((arr: unknown[]) => arr.map(number().run))\n  .map(Result.successes)\n\nvalidNumbersDecoder.run([1, true, 2, 3, 'five', 4, []])\n// {ok: true, result: [1, 2, 3, 4]}\n\nvalidNumbersDecoder.run([false, 'hi', {}])\n// {ok: true, result: []}\n\nvalidNumbersDecoder.run(false)\n// {ok: false, error: {..., message: \"expected an array, got a boolean\"}}\n```\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`unknown`[]>\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [Decoder](_decoder_.decoder.md)<`A`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`[]>\n\n___\n<a id=\"boolean\"></a>\n\n### `<Static>` boolean\n\n▸ **boolean**(): [Decoder](_decoder_.decoder.md)<`boolean`>\n\nDecoder primitive that validates booleans, and fails on all other input.\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`boolean`>\n\n___\n<a id=\"constant\"></a>\n\n### `<Static>` constant\n\n▸ **constant**(value: *`true`*): [Decoder](_decoder_.decoder.md)<`true`>\n\n▸ **constant**(value: *`false`*): [Decoder](_decoder_.decoder.md)<`false`>\n\n▸ **constant**A(value: *`A`*): [Decoder](_decoder_.decoder.md)<`A`>\n\nDecoder primitive that only matches on exact values.\n\nNote 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')`.\n\nProviding the type parameter is only necessary for type-literal strings and numbers, as detailed by this table:\n\n```\n| Decoder                      | Type                 |\n | ---------------------------- | ---------------------|\n | constant(true)               | Decoder<true>        |\n | constant(false)              | Decoder<false>       |\n | constant(null)               | Decoder<null>        |\n | constant('alaska')           | Decoder<string>      |\n | constant<'alaska'>('alaska') | Decoder<'alaska'>    |\n | constant(50)                 | Decoder<number>      |\n | constant<50>(50)             | Decoder<50>          |\n | constant([1,2,3])            | Decoder<number[]>    |\n | constant<[1,2,3]>([1,2,3])   | Decoder<[1,2,3]>     |\n | constant({x: 't'})           | Decoder<{x: string}> |\n | constant<{x: 't'}>({x: 't'}) | Decoder<{x: 't'}>    |\n```\n\nOne place where this happens is when a type-literal is in an interface:\n\n```\ninterface Bear {\n  kind: 'bear';\n  isBig: boolean;\n}\n\nconst bearDecoder1: Decoder<Bear> = object({\n  kind: constant('bear'),\n  isBig: boolean()\n});\n// Type 'Decoder<{ kind: string; isBig: boolean; }>' is not assignable to\n// type 'Decoder<Bear>'. Type 'string' is not assignable to type '\"bear\"'.\n\nconst bearDecoder2: Decoder<Bear> = object({\n  kind: constant<'bear'>('bear'),\n  isBig: boolean()\n});\n// no compiler errors\n```\n\nAnother is in type-literal unions:\n\n```\ntype animal = 'bird' | 'bear';\n\nconst animalDecoder1: Decoder<animal> = union(\n  constant('bird'),\n  constant('bear')\n);\n// Type 'Decoder<string>' is not assignable to type 'Decoder<animal>'.\n// Type 'string' is not assignable to type 'animal'.\n\nconst animalDecoder2: Decoder<animal> = union(\n  constant<'bird'>('bird'),\n  constant<'bear'>('bear')\n);\n// no compiler errors\n```\n\n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| value | `true` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`true`>\n\n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| value | `false` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`false`>\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| value | `A` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`>\n\n___\n<a id=\"dict\"></a>\n\n### `<Static>` dict\n\n▸ **dict**A(decoder: *[Decoder](_decoder_.decoder.md)<`A`>*): [Decoder](_decoder_.decoder.md)<`Record`<`string`, `A`>>\n\nDecoder for json objects where the keys are unknown strings, but the values should all be of the same type.\n\nExample:\n\n```\ndict(number()).run({chocolate: 12, vanilla: 10, mint: 37});\n// => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}}\n```\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [Decoder](_decoder_.decoder.md)<`A`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`Record`<`string`, `A`>>\n\n___\n<a id=\"fail\"></a>\n\n### `<Static>` fail\n\n▸ **fail**A(errorMessage: *`string`*): [Decoder](_decoder_.decoder.md)<`A`>\n\nDecoder that ignores the input json and always fails with `errorMessage`.\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| errorMessage | `string` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`>\n\n___\n<a id=\"intersection\"></a>\n\n### `<Static>` intersection\n\n▸ **intersection**A,B(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*): [Decoder](_decoder_.decoder.md)< `A` & `B`>\n\n▸ **intersection**A,B,C(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*): [Decoder](_decoder_.decoder.md)< `A` & `B` & `C`>\n\n▸ **intersection**A,B,C,D(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*): [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D`>\n\n▸ **intersection**A,B,C,D,E(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*, ed: *[Decoder](_decoder_.decoder.md)<`E`>*): [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D` & `E`>\n\n▸ **intersection**A,B,C,D,E,F(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*, ed: *[Decoder](_decoder_.decoder.md)<`E`>*, fd: *[Decoder](_decoder_.decoder.md)<`F`>*): [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D` & `E` & `F`>\n\n▸ **intersection**A,B,C,D,E,F,G(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*, ed: *[Decoder](_decoder_.decoder.md)<`E`>*, fd: *[Decoder](_decoder_.decoder.md)<`F`>*, gd: *[Decoder](_decoder_.decoder.md)<`G`>*): [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D` & `E` & `F` & `G`>\n\n▸ **intersection**A,B,C,D,E,F,G,H(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*, ed: *[Decoder](_decoder_.decoder.md)<`E`>*, fd: *[Decoder](_decoder_.decoder.md)<`F`>*, gd: *[Decoder](_decoder_.decoder.md)<`G`>*, hd: *[Decoder](_decoder_.decoder.md)<`H`>*): [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D` & `E` & `F` & `G` & `H`>\n\nCombines 2-8 object decoders into a decoder for the intersection of all the objects.\n\nExample:\n\n```\ninterface Pet {\n  name: string;\n  maxLegs: number;\n}\n\ninterface Cat extends Pet {\n  evil: boolean;\n}\n\nconst petDecoder: Decoder<Pet> = object({name: string(), maxLegs: number()});\nconst catDecoder: Decoder<Cat> = intersection(petDecoder, object({evil: boolean()}));\n```\n\n**Type parameters:**\n\n#### A \n#### B \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` & `B`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` & `B` & `C`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n| ed | [Decoder](_decoder_.decoder.md)<`E`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D` & `E`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n#### F \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n| ed | [Decoder](_decoder_.decoder.md)<`E`> |\n| fd | [Decoder](_decoder_.decoder.md)<`F`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D` & `E` & `F`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n#### F \n#### G \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n| ed | [Decoder](_decoder_.decoder.md)<`E`> |\n| fd | [Decoder](_decoder_.decoder.md)<`F`> |\n| gd | [Decoder](_decoder_.decoder.md)<`G`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D` & `E` & `F` & `G`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n#### F \n#### G \n#### H \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n| ed | [Decoder](_decoder_.decoder.md)<`E`> |\n| fd | [Decoder](_decoder_.decoder.md)<`F`> |\n| gd | [Decoder](_decoder_.decoder.md)<`G`> |\n| hd | [Decoder](_decoder_.decoder.md)<`H`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` & `B` & `C` & `D` & `E` & `F` & `G` & `H`>\n\n___\n<a id=\"lazy\"></a>\n\n### `<Static>` lazy\n\n▸ **lazy**A(mkDecoder: *`function`*): [Decoder](_decoder_.decoder.md)<`A`>\n\nDecoder 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.\n\nExample:\n\n```\ninterface Comment {\n  msg: string;\n  replies: Comment[];\n}\n\nconst decoder: Decoder<Comment> = object({\n  msg: string(),\n  replies: lazy(() => array(decoder))\n});\n```\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| mkDecoder | `function` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`>\n\n___\n<a id=\"number\"></a>\n\n### `<Static>` number\n\n▸ **number**(): [Decoder](_decoder_.decoder.md)<`number`>\n\nDecoder primitive that validates numbers, and fails on all other input.\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`number`>\n\n___\n<a id=\"object\"></a>\n\n### `<Static>` object\n\n▸ **object**(): [Decoder](_decoder_.decoder.md)<`Record`<`string`, `unknown`>>\n\n▸ **object**A(decoders: *[DecoderObject](../modules/_decoder_.md#decoderobject)<`A`>*): [Decoder](_decoder_.decoder.md)<`A`>\n\nAn 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`.\n\nThe `optional` and `constant` decoders are particularly useful for decoding objects that match typescript interfaces.\n\nTo decode a single field that is inside of an object see `valueAt`.\n\nExample:\n\n```\nobject({x: number(), y: number()}).run({x: 5, y: 10})\n// => {ok: true, result: {x: 5, y: 10}}\n\nobject().map(Object.keys).run({n: 1, i: [], c: {}, e: 'e'})\n// => {ok: true, result: ['n', 'i', 'c', 'e']}\n```\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`Record`<`string`, `unknown`>>\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoders | [DecoderObject](../modules/_decoder_.md#decoderobject)<`A`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`>\n\n___\n<a id=\"oneof\"></a>\n\n### `<Static>` oneOf\n\n▸ **oneOf**A(...decoders: *[Decoder](_decoder_.decoder.md)<`A`>[]*): [Decoder](_decoder_.decoder.md)<`A`>\n\nDecoder that attempts to run each decoder in `decoders` and either succeeds with the first successful decoder, or fails after all decoders have failed.\n\nNote 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.\n\nExamples:\n\n```\noneOf(string(), number().map(String))\noneOf(constant('start'), constant('stop'), succeed('unknown'))\n```\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| `Rest` decoders | [Decoder](_decoder_.decoder.md)<`A`>[] |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`>\n\n___\n<a id=\"optional\"></a>\n\n### `<Static>` optional\n\n▸ **optional**A(decoder: *[Decoder](_decoder_.decoder.md)<`A`>*): [Decoder](_decoder_.decoder.md)< `undefined` &#124; `A`>\n\nDecoder for values that may be `undefined`. This is primarily helpful for decoding interfaces with optional fields.\n\nExample:\n\n```\ninterface User {\n  id: number;\n  isOwner?: boolean;\n}\n\nconst decoder: Decoder<User> = object({\n  id: number(),\n  isOwner: optional(boolean())\n});\n```\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [Decoder](_decoder_.decoder.md)<`A`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `undefined` &#124; `A`>\n\n___\n<a id=\"string\"></a>\n\n### `<Static>` string\n\n▸ **string**(): [Decoder](_decoder_.decoder.md)<`string`>\n\nDecoder primitive that validates strings, and fails on all other input.\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`string`>\n\n___\n<a id=\"succeed\"></a>\n\n### `<Static>` succeed\n\n▸ **succeed**A(fixedValue: *`A`*): [Decoder](_decoder_.decoder.md)<`A`>\n\nDecoder that ignores the input json and always succeeds with `fixedValue`.\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| fixedValue | `A` |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`>\n\n___\n<a id=\"tuple\"></a>\n\n### `<Static>` tuple\n\n▸ **tuple**A(decoder: *[[Decoder](_decoder_.decoder.md)<`A`>]*): [Decoder](_decoder_.decoder.md)<[`A`]>\n\n▸ **tuple**A,B(decoder: *[[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>]*): [Decoder](_decoder_.decoder.md)<[`A`, `B`]>\n\n▸ **tuple**A,B,C(decoder: *[[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>]*): [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`]>\n\n▸ **tuple**A,B,C,D(decoder: *[[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>]*): [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`]>\n\n▸ **tuple**A,B,C,D,E(decoder: *[[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>, [Decoder](_decoder_.decoder.md)<`E`>]*): [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`, `E`]>\n\n▸ **tuple**A,B,C,D,E,F(decoder: *[[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>, [Decoder](_decoder_.decoder.md)<`E`>, [Decoder](_decoder_.decoder.md)<`F`>]*): [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`, `E`, `F`]>\n\n▸ **tuple**A,B,C,D,E,F,G(decoder: *[[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>, [Decoder](_decoder_.decoder.md)<`E`>, [Decoder](_decoder_.decoder.md)<`F`>, [Decoder](_decoder_.decoder.md)<`G`>]*): [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`, `E`, `F`, `G`]>\n\n▸ **tuple**A,B,C,D,E,F,G,H(decoder: *[[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>, [Decoder](_decoder_.decoder.md)<`E`>, [Decoder](_decoder_.decoder.md)<`F`>, [Decoder](_decoder_.decoder.md)<`G`>, [Decoder](_decoder_.decoder.md)<`H`>]*): [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`, `E`, `F`, `G`, `H`]>\n\nDecoder for fixed-length arrays, aka Tuples.\n\nSupports up to 8-tuples.\n\nExample:\n\n```\ntuple([number(), number(), string()]).run([5, 10, 'px'])\n// => {ok: true, result: [5, 10, 'px']}\n```\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [[Decoder](_decoder_.decoder.md)<`A`>] |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<[`A`]>\n\n**Type parameters:**\n\n#### A \n#### B \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>] |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<[`A`, `B`]>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>] |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`]>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>] |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`]>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>, [Decoder](_decoder_.decoder.md)<`E`>] |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`, `E`]>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n#### F \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>, [Decoder](_decoder_.decoder.md)<`E`>, [Decoder](_decoder_.decoder.md)<`F`>] |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`, `E`, `F`]>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n#### F \n#### G \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>, [Decoder](_decoder_.decoder.md)<`E`>, [Decoder](_decoder_.decoder.md)<`F`>, [Decoder](_decoder_.decoder.md)<`G`>] |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`, `E`, `F`, `G`]>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n#### F \n#### G \n#### H \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| decoder | [[Decoder](_decoder_.decoder.md)<`A`>, [Decoder](_decoder_.decoder.md)<`B`>, [Decoder](_decoder_.decoder.md)<`C`>, [Decoder](_decoder_.decoder.md)<`D`>, [Decoder](_decoder_.decoder.md)<`E`>, [Decoder](_decoder_.decoder.md)<`F`>, [Decoder](_decoder_.decoder.md)<`G`>, [Decoder](_decoder_.decoder.md)<`H`>] |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<[`A`, `B`, `C`, `D`, `E`, `F`, `G`, `H`]>\n\n___\n<a id=\"union\"></a>\n\n### `<Static>` union\n\n▸ **union**A,B(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*): [Decoder](_decoder_.decoder.md)< `A` &#124; `B`>\n\n▸ **union**A,B,C(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*): [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C`>\n\n▸ **union**A,B,C,D(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*): [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D`>\n\n▸ **union**A,B,C,D,E(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*, ed: *[Decoder](_decoder_.decoder.md)<`E`>*): [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D` &#124; `E`>\n\n▸ **union**A,B,C,D,E,F(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*, ed: *[Decoder](_decoder_.decoder.md)<`E`>*, fd: *[Decoder](_decoder_.decoder.md)<`F`>*): [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D` &#124; `E` &#124; `F`>\n\n▸ **union**A,B,C,D,E,F,G(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*, ed: *[Decoder](_decoder_.decoder.md)<`E`>*, fd: *[Decoder](_decoder_.decoder.md)<`F`>*, gd: *[Decoder](_decoder_.decoder.md)<`G`>*): [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D` &#124; `E` &#124; `F` &#124; `G`>\n\n▸ **union**A,B,C,D,E,F,G,H(ad: *[Decoder](_decoder_.decoder.md)<`A`>*, bd: *[Decoder](_decoder_.decoder.md)<`B`>*, cd: *[Decoder](_decoder_.decoder.md)<`C`>*, dd: *[Decoder](_decoder_.decoder.md)<`D`>*, ed: *[Decoder](_decoder_.decoder.md)<`E`>*, fd: *[Decoder](_decoder_.decoder.md)<`F`>*, gd: *[Decoder](_decoder_.decoder.md)<`G`>*, hd: *[Decoder](_decoder_.decoder.md)<`H`>*): [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D` &#124; `E` &#124; `F` &#124; `G` &#124; `H`>\n\nCombines 2-8 decoders of disparate types into a decoder for the union of all the types.\n\nIf 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.\n\nExample:\n\n```\ntype C = {a: string} | {b: number};\n\nconst unionDecoder: Decoder<C> = union(object({a: string()}), object({b: number()}));\nconst oneOfDecoder: Decoder<C> = oneOf(object<C>({a: string()}), object<C>({b: number()}));\n```\n\n**Type parameters:**\n\n#### A \n#### B \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` &#124; `B`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n| ed | [Decoder](_decoder_.decoder.md)<`E`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D` &#124; `E`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n#### F \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n| ed | [Decoder](_decoder_.decoder.md)<`E`> |\n| fd | [Decoder](_decoder_.decoder.md)<`F`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D` &#124; `E` &#124; `F`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n#### F \n#### G \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n| ed | [Decoder](_decoder_.decoder.md)<`E`> |\n| fd | [Decoder](_decoder_.decoder.md)<`F`> |\n| gd | [Decoder](_decoder_.decoder.md)<`G`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D` &#124; `E` &#124; `F` &#124; `G`>\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### D \n#### E \n#### F \n#### G \n#### H \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| ad | [Decoder](_decoder_.decoder.md)<`A`> |\n| bd | [Decoder](_decoder_.decoder.md)<`B`> |\n| cd | [Decoder](_decoder_.decoder.md)<`C`> |\n| dd | [Decoder](_decoder_.decoder.md)<`D`> |\n| ed | [Decoder](_decoder_.decoder.md)<`E`> |\n| fd | [Decoder](_decoder_.decoder.md)<`F`> |\n| gd | [Decoder](_decoder_.decoder.md)<`G`> |\n| hd | [Decoder](_decoder_.decoder.md)<`H`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)< `A` &#124; `B` &#124; `C` &#124; `D` &#124; `E` &#124; `F` &#124; `G` &#124; `H`>\n\n___\n<a id=\"unknownjson\"></a>\n\n### `<Static>` unknownJson\n\n▸ **unknownJson**(): [Decoder](_decoder_.decoder.md)<`unknown`>\n\nDecoder identity function which always succeeds and types the result as `unknown`.\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`unknown`>\n\n___\n<a id=\"valueat\"></a>\n\n### `<Static>` valueAt\n\n▸ **valueAt**A(paths: *( `string` &#124; `number`)[]*, decoder: *[Decoder](_decoder_.decoder.md)<`A`>*): [Decoder](_decoder_.decoder.md)<`A`>\n\nDecoder 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.\n\nExample:\n\n```\nconst decoder = valueAt(['a', 'b', 0], string());\n\ndecoder.run({a: {b: ['surprise!']}})\n// => {ok: true, result: 'surprise!'}\n\ndecoder.run({a: {x: 'cats'}})\n// => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}}\n```\n\nNote 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.\n\n```\nconst optionalDecoder = valueAt(['a', 'b', 'c'], optional(string()));\n\noptionalDecoder.run({a: {b: {c: 'surprise!'}}})\n// => {ok: true, result: 'surprise!'}\n\noptionalDecoder.run({a: {b: 'cats'}})\n// => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got \"cats\"'}\n\noptionalDecoder.run({a: {b: {z: 1}}})\n// => {ok: true, result: undefined}\n```\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| paths | ( `string` &#124; `number`)[] |\n| decoder | [Decoder](_decoder_.decoder.md)<`A`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`>\n\n___\n<a id=\"withdefault\"></a>\n\n### `<Static>` withDefault\n\n▸ **withDefault**A(defaultValue: *`A`*, decoder: *[Decoder](_decoder_.decoder.md)<`A`>*): [Decoder](_decoder_.decoder.md)<`A`>\n\nDecoder that always succeeds with either the decoded value, or a fallback default value.\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| defaultValue | `A` |\n| decoder | [Decoder](_decoder_.decoder.md)<`A`> |\n\n**Returns:** [Decoder](_decoder_.decoder.md)<`A`>\n\n___\n\n"
  },
  {
    "path": "docs/interfaces/_decoder_.decodererror.md",
    "content": "[@mojotech/json-type-validation](../README.md) > [\"decoder\"](../modules/_decoder_.md) > [DecoderError](../interfaces/_decoder_.decodererror.md)\n\n# Interface: DecoderError\n\nInformation describing how json data failed to match a decoder. Includes the full input json, since in most cases it's useless to know how a decoder failed without also seeing the malformed data.\n\n## Hierarchy\n\n**DecoderError**\n\n## Index\n\n### Properties\n\n* [at](_decoder_.decodererror.md#at)\n* [input](_decoder_.decodererror.md#input)\n* [kind](_decoder_.decodererror.md#kind)\n* [message](_decoder_.decodererror.md#message)\n\n---\n\n## Properties\n\n<a id=\"at\"></a>\n\n###  at\n\n**● at**: *`string`*\n\n___\n<a id=\"input\"></a>\n\n###  input\n\n**● input**: *`unknown`*\n\n___\n<a id=\"kind\"></a>\n\n###  kind\n\n**● kind**: *\"DecoderError\"*\n\n___\n<a id=\"message\"></a>\n\n###  message\n\n**● message**: *`string`*\n\n___\n\n"
  },
  {
    "path": "docs/interfaces/_result_.err.md",
    "content": "[@mojotech/json-type-validation](../README.md) > [\"result\"](../modules/_result_.md) > [Err](../interfaces/_result_.err.md)\n\n# Interface: Err\n\nThe error type variant for `Result`. Denotes that some error occurred before the result was computed.\n\n## Type parameters\n#### E \n## Hierarchy\n\n**Err**\n\n## Index\n\n### Properties\n\n* [error](_result_.err.md#error)\n* [ok](_result_.err.md#ok)\n\n---\n\n## Properties\n\n<a id=\"error\"></a>\n\n###  error\n\n**● error**: *`E`*\n\n___\n<a id=\"ok\"></a>\n\n###  ok\n\n**● ok**: *`false`*\n\n___\n\n"
  },
  {
    "path": "docs/interfaces/_result_.ok.md",
    "content": "[@mojotech/json-type-validation](../README.md) > [\"result\"](../modules/_result_.md) > [Ok](../interfaces/_result_.ok.md)\n\n# Interface: Ok\n\nThe success type variant for `Result`. Denotes that a result value was computed with no errors.\n\n## Type parameters\n#### V \n## Hierarchy\n\n**Ok**\n\n## Index\n\n### Properties\n\n* [ok](_result_.ok.md#ok)\n* [result](_result_.ok.md#result)\n\n---\n\n## Properties\n\n<a id=\"ok\"></a>\n\n###  ok\n\n**● ok**: *`true`*\n\n___\n<a id=\"result\"></a>\n\n###  result\n\n**● result**: *`V`*\n\n___\n\n"
  },
  {
    "path": "docs/modules/_combinators_.md",
    "content": "[@mojotech/json-type-validation](../README.md) > [\"combinators\"](../modules/_combinators_.md)\n\n# External module: \"combinators\"\n\n## Index\n\n### Variables\n\n* [anyJson](_combinators_.md#anyjson)\n* [array](_combinators_.md#array)\n* [boolean](_combinators_.md#boolean)\n* [constant](_combinators_.md#constant)\n* [dict](_combinators_.md#dict)\n* [fail](_combinators_.md#fail)\n* [intersection](_combinators_.md#intersection)\n* [lazy](_combinators_.md#lazy)\n* [number](_combinators_.md#number)\n* [object](_combinators_.md#object)\n* [oneOf](_combinators_.md#oneof)\n* [optional](_combinators_.md#optional)\n* [string](_combinators_.md#string)\n* [succeed](_combinators_.md#succeed)\n* [tuple](_combinators_.md#tuple)\n* [union](_combinators_.md#union)\n* [unknownJson](_combinators_.md#unknownjson)\n* [valueAt](_combinators_.md#valueat)\n* [withDefault](_combinators_.md#withdefault)\n\n---\n\n## Variables\n\n<a id=\"anyjson\"></a>\n\n### `<Const>` anyJson\n\n**● anyJson**: *[anyJson]()* =  Decoder.anyJson\n\nSee `Decoder.anyJson`\n\n___\n<a id=\"array\"></a>\n\n### `<Const>` array\n\n**● array**: *[array](../classes/_decoder_.decoder.md#array)* =  Decoder.array\n\nSee `Decoder.array`\n\n___\n<a id=\"boolean\"></a>\n\n### `<Const>` boolean\n\n**● boolean**: *[boolean](../classes/_decoder_.decoder.md#boolean)* =  Decoder.boolean\n\nSee `Decoder.boolean`\n\n___\n<a id=\"constant\"></a>\n\n### `<Const>` constant\n\n**● constant**: *[constant](../classes/_decoder_.decoder.md#constant)* =  Decoder.constant\n\nSee `Decoder.constant`\n\n___\n<a id=\"dict\"></a>\n\n### `<Const>` dict\n\n**● dict**: *[dict]()* =  Decoder.dict\n\nSee `Decoder.dict`\n\n___\n<a id=\"fail\"></a>\n\n### `<Const>` fail\n\n**● fail**: *[fail]()* =  Decoder.fail\n\nSee `Decoder.fail`\n\n___\n<a id=\"intersection\"></a>\n\n### `<Const>` intersection\n\n**● intersection**: *[intersection](../classes/_decoder_.decoder.md#intersection)* =  Decoder.intersection\n\nSee `Decoder.intersection`\n\n___\n<a id=\"lazy\"></a>\n\n### `<Const>` lazy\n\n**● lazy**: *[lazy]()* =  Decoder.lazy\n\nSee `Decoder.lazy`\n\n___\n<a id=\"number\"></a>\n\n### `<Const>` number\n\n**● number**: *[number](../classes/_decoder_.decoder.md#number)* =  Decoder.number\n\nSee `Decoder.number`\n\n___\n<a id=\"object\"></a>\n\n### `<Const>` object\n\n**● object**: *[object](../classes/_decoder_.decoder.md#object)* =  Decoder.object\n\nSee `Decoder.object`\n\n___\n<a id=\"oneof\"></a>\n\n### `<Const>` oneOf\n\n**● oneOf**: *[oneOf]()* =  Decoder.oneOf\n\nSee `Decoder.oneOf`\n\n___\n<a id=\"optional\"></a>\n\n### `<Const>` optional\n\n**● optional**: *[optional]()* =  Decoder.optional\n\nSee `Decoder.optional`\n\n___\n<a id=\"string\"></a>\n\n### `<Const>` string\n\n**● string**: *[string](../classes/_decoder_.decoder.md#string)* =  Decoder.string\n\nSee `Decoder.string`\n\n___\n<a id=\"succeed\"></a>\n\n### `<Const>` succeed\n\n**● succeed**: *[succeed]()* =  Decoder.succeed\n\nSee `Decoder.succeed`\n\n___\n<a id=\"tuple\"></a>\n\n### `<Const>` tuple\n\n**● tuple**: *[tuple](../classes/_decoder_.decoder.md#tuple)* =  Decoder.tuple\n\nSee `Decoder.tuple`\n\n___\n<a id=\"union\"></a>\n\n### `<Const>` union\n\n**● union**: *[union](../classes/_decoder_.decoder.md#union)* =  Decoder.union\n\nSee `Decoder.union`\n\n___\n<a id=\"unknownjson\"></a>\n\n### `<Const>` unknownJson\n\n**● unknownJson**: *`function`* =  Decoder.unknownJson\n\nSee `Decoder.unknownJson`\n\n#### Type declaration\n▸(): [Decoder](../classes/_decoder_.decoder.md)<`unknown`>\n\n**Returns:** [Decoder](../classes/_decoder_.decoder.md)<`unknown`>\n\n___\n<a id=\"valueat\"></a>\n\n### `<Const>` valueAt\n\n**● valueAt**: *[valueAt]()* =  Decoder.valueAt\n\nSee `Decoder.valueAt`\n\n___\n<a id=\"withdefault\"></a>\n\n### `<Const>` withDefault\n\n**● withDefault**: *[withDefault]()* =  Decoder.withDefault\n\nSee `Decoder.withDefault`\n\n___\n\n"
  },
  {
    "path": "docs/modules/_decoder_.md",
    "content": "[@mojotech/json-type-validation](../README.md) > [\"decoder\"](../modules/_decoder_.md)\n\n# External module: \"decoder\"\n\n## Index\n\n### Classes\n\n* [Decoder](../classes/_decoder_.decoder.md)\n\n### Interfaces\n\n* [DecoderError](../interfaces/_decoder_.decodererror.md)\n\n### Type aliases\n\n* [DecoderObject](_decoder_.md#decoderobject)\n\n### Functions\n\n* [isDecoderError](_decoder_.md#isdecodererror)\n\n---\n\n## Type aliases\n\n<a id=\"decoderobject\"></a>\n\n###  DecoderObject\n\n**ΤDecoderObject**: *`object`*\n\nDefines a mapped type over an interface `A`. `DecoderObject<A>` is an interface that has all the keys or `A`, but each key's property type is mapped to a decoder for that type. This type is used when creating decoders for objects.\n\nExample:\n\n```\ninterface X {\n  a: boolean;\n  b: string;\n}\n\nconst decoderObject: DecoderObject<X> = {\n  a: boolean(),\n  b: string()\n}\n```\n\n#### Type declaration\n\n___\n\n## Functions\n\n<a id=\"isdecodererror\"></a>\n\n### `<Const>` isDecoderError\n\n▸ **isDecoderError**(a: *`any`*): `boolean`\n\nType guard for `DecoderError`. One use case of the type guard is in the `catch` of a promise. Typescript types the error argument of `catch` as `any`, so when dealing with a decoder as a promise you may need to distinguish between a `DecoderError` and an error string.\n\n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| a | `any` |\n\n**Returns:** `boolean`\n\n___\n\n"
  },
  {
    "path": "docs/modules/_index_.md",
    "content": "[@mojotech/json-type-validation](../README.md) > [\"index\"](../modules/_index_.md)\n\n# External module: \"index\"\n\n## Index\n\n---\n\n"
  },
  {
    "path": "docs/modules/_result_.md",
    "content": "[@mojotech/json-type-validation](../README.md) > [\"result\"](../modules/_result_.md)\n\n# External module: \"result\"\n\n## Index\n\n### Interfaces\n\n* [Err](../interfaces/_result_.err.md)\n* [Ok](../interfaces/_result_.ok.md)\n\n### Type aliases\n\n* [Result](_result_.md#result)\n\n### Functions\n\n* [andThen](_result_.md#andthen)\n* [asPromise](_result_.md#aspromise)\n* [err](_result_.md#err-1)\n* [isErr](_result_.md#iserr)\n* [isOk](_result_.md#isok)\n* [map](_result_.md#map)\n* [map2](_result_.md#map2)\n* [mapError](_result_.md#maperror)\n* [ok](_result_.md#ok-1)\n* [successes](_result_.md#successes)\n* [withDefault](_result_.md#withdefault)\n* [withException](_result_.md#withexception)\n\n---\n\n## Type aliases\n\n<a id=\"result\"></a>\n\n###  Result\n\n**ΤResult**: * [Ok](../interfaces/_result_.ok.md)<`V`> &#124; [Err](../interfaces/_result_.err.md)<`E`>\n*\n\nThe result of a computation that may fail. The decoding function `Decoder.run` returns a `Result`. The value of a `Result` is either `Ok` if the computation succeeded, or `Err` if there was some failure in the process.\n\n___\n\n## Functions\n\n<a id=\"andthen\"></a>\n\n### `<Const>` andThen\n\n▸ **andThen**A,B,E(f: *`function`*, r: *[Result](_result_.md#result)<`A`, `E`>*): [Result](_result_.md#result)<`B`, `E`>\n\nChain together a sequence of computations that may fail, similar to a `Promise`. If the first computation fails then the error will propagate through. If it succeeds, then `f` will be applied to the value, returning a new `Result`.\n\n**Type parameters:**\n\n#### A \n#### B \n#### E \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| f | `function` |\n| r | [Result](_result_.md#result)<`A`, `E`> |\n\n**Returns:** [Result](_result_.md#result)<`B`, `E`>\n\n___\n<a id=\"aspromise\"></a>\n\n### `<Const>` asPromise\n\n▸ **asPromise**V(r: *[Result](_result_.md#result)<`V`, `any`>*): `Promise`<`V`>\n\nCreate a `Promise` that either resolves with the result of `Ok` or rejects with the error of `Err`.\n\n**Type parameters:**\n\n#### V \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| r | [Result](_result_.md#result)<`V`, `any`> |\n\n**Returns:** `Promise`<`V`>\n\n___\n<a id=\"err-1\"></a>\n\n### `<Const>` err\n\n▸ **err**E(error: *`E`*): [Err](../interfaces/_result_.err.md)<`E`>\n\nWraps errors in an `Err` type.\n\nExample: `err('on fire') // => {ok: false, error: 'on fire'}`\n\n**Type parameters:**\n\n#### E \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| error | `E` |\n\n**Returns:** [Err](../interfaces/_result_.err.md)<`E`>\n\n___\n<a id=\"iserr\"></a>\n\n### `<Const>` isErr\n\n▸ **isErr**E(r: *[Result](_result_.md#result)<`any`, `E`>*): `boolean`\n\nTypeguard for `Err`.\n\n**Type parameters:**\n\n#### E \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| r | [Result](_result_.md#result)<`any`, `E`> |\n\n**Returns:** `boolean`\n\n___\n<a id=\"isok\"></a>\n\n### `<Const>` isOk\n\n▸ **isOk**V(r: *[Result](_result_.md#result)<`V`, `any`>*): `boolean`\n\nTypeguard for `Ok`.\n\n**Type parameters:**\n\n#### V \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| r | [Result](_result_.md#result)<`V`, `any`> |\n\n**Returns:** `boolean`\n\n___\n<a id=\"map\"></a>\n\n### `<Const>` map\n\n▸ **map**A,B,E(f: *`function`*, r: *[Result](_result_.md#result)<`A`, `E`>*): [Result](_result_.md#result)<`B`, `E`>\n\nApply `f` to the result of an `Ok`, or pass the error through.\n\n**Type parameters:**\n\n#### A \n#### B \n#### E \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| f | `function` |\n| r | [Result](_result_.md#result)<`A`, `E`> |\n\n**Returns:** [Result](_result_.md#result)<`B`, `E`>\n\n___\n<a id=\"map2\"></a>\n\n### `<Const>` map2\n\n▸ **map2**A,B,C,E(f: *`function`*, ar: *[Result](_result_.md#result)<`A`, `E`>*, br: *[Result](_result_.md#result)<`B`, `E`>*): [Result](_result_.md#result)<`C`, `E`>\n\nApply `f` to the result of two `Ok`s, or pass an error through. If both `Result`s are errors then the first one is returned.\n\n**Type parameters:**\n\n#### A \n#### B \n#### C \n#### E \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| f | `function` |\n| ar | [Result](_result_.md#result)<`A`, `E`> |\n| br | [Result](_result_.md#result)<`B`, `E`> |\n\n**Returns:** [Result](_result_.md#result)<`C`, `E`>\n\n___\n<a id=\"maperror\"></a>\n\n### `<Const>` mapError\n\n▸ **mapError**V,A,B(f: *`function`*, r: *[Result](_result_.md#result)<`V`, `A`>*): [Result](_result_.md#result)<`V`, `B`>\n\nApply `f` to the error of an `Err`, or pass the success through.\n\n**Type parameters:**\n\n#### V \n#### A \n#### B \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| f | `function` |\n| r | [Result](_result_.md#result)<`V`, `A`> |\n\n**Returns:** [Result](_result_.md#result)<`V`, `B`>\n\n___\n<a id=\"ok-1\"></a>\n\n### `<Const>` ok\n\n▸ **ok**V(result: *`V`*): [Ok](../interfaces/_result_.ok.md)<`V`>\n\nWraps values in an `Ok` type.\n\nExample: `ok(5) // => {ok: true, result: 5}`\n\n**Type parameters:**\n\n#### V \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| result | `V` |\n\n**Returns:** [Ok](../interfaces/_result_.ok.md)<`V`>\n\n___\n<a id=\"successes\"></a>\n\n### `<Const>` successes\n\n▸ **successes**A(results: *[Result](_result_.md#result)<`A`, `any`>[]*): `A`[]\n\nGiven an array of `Result`s, return the successful values.\n\n**Type parameters:**\n\n#### A \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| results | [Result](_result_.md#result)<`A`, `any`>[] |\n\n**Returns:** `A`[]\n\n___\n<a id=\"withdefault\"></a>\n\n### `<Const>` withDefault\n\n▸ **withDefault**V(defaultValue: *`V`*, r: *[Result](_result_.md#result)<`V`, `any`>*): `V`\n\nUnwraps a `Result` and returns either the result of an `Ok`, or `defaultValue`.\n\nExample:\n\n```\nResult.withDefault(5, number().run(json))\n```\n\nIt would be nice if `Decoder` had an instance method that mirrored this function. Such a method would look something like this:\n\n```\nclass Decoder<A> {\n  runWithDefault = (defaultValue: A, json: any): A =>\n    Result.withDefault(defaultValue, this.run(json));\n}\n\nnumber().runWithDefault(5, json)\n```\n\nUnfortunately, the type of `defaultValue: A` on the method causes issues with type inference on the `object` decoder in some situations. While these inference issues can be solved by providing the optional type argument for `object`s, the extra trouble and confusion doesn't seem worth it.\n\n**Type parameters:**\n\n#### V \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| defaultValue | `V` |\n| r | [Result](_result_.md#result)<`V`, `any`> |\n\n**Returns:** `V`\n\n___\n<a id=\"withexception\"></a>\n\n### `<Const>` withException\n\n▸ **withException**V(r: *[Result](_result_.md#result)<`V`, `any`>*): `V`\n\nReturn the successful result, or throw an error.\n\n**Type parameters:**\n\n#### V \n**Parameters:**\n\n| Param | Type |\n| ------ | ------ |\n| r | [Result](_result_.md#result)<`V`, `any`> |\n\n**Returns:** `V`\n\n___\n\n"
  },
  {
    "path": "nix-files/default.nix",
    "content": "{ nixpkgsFn ? import ./nixpkgs.nix\n, system ? null }:\nlet nixpkgs = nixpkgsFn ({\n      # extra config goes here\n    } // ( if system == null then {} else { inherit system; } ));\nin\nnixpkgs.stdenv.mkDerivation {\n  name = \"json-type-validator\";\n  buildInputs = with nixpkgs; [ nodejs yarn git ];\n  src = \"./\";\n\n  builder = builtins.toFile \"builder.sh\" ''\n    echo \"Use this derivation with nix-shell only\"\n\n    exit 1\n  '';\n\n  shellHook = ''\n    # Get to the source directory\n    cd $src\n    # Install any new dependencies\n    yarn\n    # Add node_modules to path\n    export PATH=$src/node_modules/bin:$PATH\n  '';\n}\n"
  },
  {
    "path": "nix-files/nixpkgs.nix",
    "content": "let source = ''\n      {\n        \"owner\": \"NixOS\",\n        \"repo\": \"nixpkgs-channels\",\n        \"rev\": \"aebdc892d6aa6834a083fb8b56c43578712b0dab\",\n        \"sha256\": \"1bcpjc7f1ff5k7vf5rwwb7g7m4j238hi4ssnx7xqglr7hj4ms0cz\"\n      }\n      '';\nin\nimport ((import <nixpkgs> {}).fetchFromGitHub (builtins.fromJSON (source)))\n"
  },
  {
    "path": "nix-files/shell.nix",
    "content": "{ nixpkgsFn ? import ./nixpkgs.nix\n, package ? ./default.nix\n}:\n(import package { inherit nixpkgsFn; })\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"@mojotech/json-type-validation\",\n  \"version\": \"3.1.0\",\n  \"description\": \"runtime type checking and validation of untyped JSON data\",\n  \"keywords\": [\n    \"TypeScript\",\n    \"JSON\"\n  ],\n  \"main\": \"dist/index.js\",\n  \"module\": \"dist/index.es5.js\",\n  \"typings\": \"dist/types/index.d.ts\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"author\": \"Elias Mulhall <elias@mojotech.com>\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/mojotech/json-type-validation\"\n  },\n  \"bugs\": {\n    \"url\": \"https://github.com/mojotech/json-type-validation/issues\"\n  },\n  \"homepage\": \"https://github.com/mojotech/json-type-validation\",\n  \"license\": \"MIT\",\n  \"engines\": {\n    \"node\": \">=6.0.0\"\n  },\n  \"scripts\": {\n    \"lint\": \"tslint -t codeFrame --project tsconfig-test.json\",\n    \"prebuild\": \"rimraf dist\",\n    \"build\": \"tsc --module commonjs --outDir dist/lib && rollup -c rollup.config.ts && typedoc --out docs --target es6 --theme markdown --readme DOCS.md --mdHideSources --mode modules --excludeNotExported src\",\n    \"start\": \"rollup -c rollup.config.ts -w\",\n    \"test\": \"jest\",\n    \"test:watch\": \"jest --watch\",\n    \"test:prod\": \"npm run lint && npm run test -- --coverage --no-cache\",\n    \"typecheck\": \"tsc --lib es2015 --noEmit --strict test/**.ts\",\n    \"typecheck:watch\": \"tsc -w --lib es2015 --noEmit --strict test/**.ts\"\n  },\n  \"jest\": {\n    \"transform\": {\n      \".(ts|tsx)\": \"<rootDir>/node_modules/ts-jest/preprocessor.js\"\n    },\n    \"testRegex\": \"(/__tests__/.*|\\\\.(test|spec))\\\\.(ts|tsx|js)$\",\n    \"moduleFileExtensions\": [\n      \"ts\",\n      \"tsx\",\n      \"js\"\n    ],\n    \"coveragePathIgnorePatterns\": [\n      \"/node_modules/\",\n      \"/test/\"\n    ],\n    \"coverageThreshold\": {\n      \"global\": {\n        \"branches\": 90,\n        \"functions\": 95,\n        \"lines\": 95,\n        \"statements\": 95\n      }\n    },\n    \"collectCoverage\": true\n  },\n  \"devDependencies\": {\n    \"@types/jest\": \"^22.2.3\",\n    \"@types/node\": \"^10.5.3\",\n    \"@types/lodash\": \"^4.5.0\",\n    \"colors\": \"^1.1.2\",\n    \"cross-env\": \"^5.0.1\",\n    \"jest\": \"^22.0.2\",\n    \"prettier\": \"^1.4.4\",\n    \"rimraf\": \"^2.6.1\",\n    \"rollup\": \"^0.53.0\",\n    \"rollup-plugin-commonjs\": \"^8.0.2\",\n    \"rollup-plugin-node-resolve\": \"^3.0.0\",\n    \"rollup-plugin-sourcemaps\": \"^0.4.2\",\n    \"rollup-plugin-typescript2\": \"^0.9.0\",\n    \"ts-jest\": \"^22.0.0\",\n    \"ts-node\": \"^4.1.0\",\n    \"tslint\": \"^5.11.0\",\n    \"tslint-config-prettier\": \"^1.14.0\",\n    \"tslint-config-standard\": \"^7.1.0\",\n    \"typedoc\": \"^0.13.0\",\n    \"typedoc-plugin-markdown\": \"^1.0.13\",\n    \"typescript\": \"~3.1.0\"\n  },\n  \"dependencies\": {\n    \"lodash\": \"^4.5.0\"\n  }\n}\n"
  },
  {
    "path": "rollup.config.ts",
    "content": "import resolve from 'rollup-plugin-node-resolve';\nimport sourceMaps from 'rollup-plugin-sourcemaps';\nimport typescript from 'rollup-plugin-typescript2';\n\nconst pkg = require('./package.json');\n\nexport default {\n  input: `src/index.ts`,\n  output: [\n    {\n      file: pkg.main,\n      name: 'index',\n      format: 'cjs',\n      sourcemap: true\n    },\n    {\n      file: pkg.module,\n      format: 'es',\n      sourcemap: true\n    }\n  ],\n  external: id => {\n    return id.includes('/node_modules/');\n  },\n  watch: {\n    include: 'src/**'\n  },\n  plugins: [\n    // Compile TypeScript files\n    typescript({\n      useTsconfigDeclarationDir: true\n    }),\n    resolve(),\n\n    // Resolve source maps to the original source\n    sourceMaps()\n  ]\n};\n"
  },
  {
    "path": "src/combinators.ts",
    "content": "import {Decoder} from './decoder';\n\n/* tslint:disable:variable-name */\n\n/** See `Decoder.string` */\nexport const string = Decoder.string;\n\n/** See `Decoder.number` */\nexport const number = Decoder.number;\n\n/** See `Decoder.boolean` */\nexport const boolean = Decoder.boolean;\n\n/** See `Decoder.anyJson` */\nexport const anyJson = Decoder.anyJson;\n\n/** See `Decoder.unknownJson` */\nexport const unknownJson: () => Decoder<unknown> = Decoder.unknownJson;\n\n/** See `Decoder.constant` */\nexport const constant = Decoder.constant;\n\n/** See `Decoder.object` */\nexport const object = Decoder.object;\n\n/** See `Decoder.array` */\nexport const array = Decoder.array;\n\n/** See `Decoder.tuple` */\nexport const tuple = Decoder.tuple;\n\n/** See `Decoder.dict` */\nexport const dict = Decoder.dict;\n\n/** See `Decoder.optional` */\nexport const optional = Decoder.optional;\n\n/** See `Decoder.oneOf` */\nexport const oneOf = Decoder.oneOf;\n\n/** See `Decoder.union` */\nexport const union = Decoder.union;\n\n/** See `Decoder.intersection` */\nexport const intersection = Decoder.intersection;\n\n/** See `Decoder.withDefault` */\nexport const withDefault = Decoder.withDefault;\n\n/** See `Decoder.valueAt` */\nexport const valueAt = Decoder.valueAt;\n\n/** See `Decoder.succeed` */\nexport const succeed = Decoder.succeed;\n\n/** See `Decoder.fail` */\nexport const fail = Decoder.fail;\n\n/** See `Decoder.lazy` */\nexport const lazy = Decoder.lazy;\n"
  },
  {
    "path": "src/decoder.ts",
    "content": "import * as Result from './result';\nimport isEqual from \"lodash/isEqual\"\n\n/**\n * Information describing how json data failed to match a decoder.\n * Includes the full input json, since in most cases it's useless to know how a\n * decoder failed without also seeing the malformed data.\n */\nexport interface DecoderError {\n  kind: 'DecoderError';\n  input: unknown;\n  at: string;\n  message: string;\n}\n\n/**\n * Alias for the result of the `Decoder.run` method. On success returns `Ok`\n * with the decoded value of type `A`, on failure returns `Err` containing a\n * `DecoderError`.\n */\ntype RunResult<A> = Result.Result<A, DecoderError>;\n\n/**\n * Alias for the result of the internal `Decoder.decode` method. Since `decode`\n * is a private function it returns a partial decoder error on failure, which\n * will be completed and polished when handed off to the `run` method.\n */\ntype DecodeResult<A> = Result.Result<A, Partial<DecoderError>>;\n\n/**\n * Defines a mapped type over an interface `A`. `DecoderObject<A>` is an\n * interface that has all the keys or `A`, but each key's property type is\n * mapped to a decoder for that type. This type is used when creating decoders\n * for objects.\n *\n * Example:\n * ```\n * interface X {\n *   a: boolean;\n *   b: string;\n * }\n *\n * const decoderObject: DecoderObject<X> = {\n *   a: boolean(),\n *   b: string()\n * }\n * ```\n */\nexport type DecoderObject<A> = {[t in keyof A]: Decoder<A[t]>};\n\n/**\n * Type guard for `DecoderError`. One use case of the type guard is in the\n * `catch` of a promise. Typescript types the error argument of `catch` as\n * `any`, so when dealing with a decoder as a promise you may need to\n * distinguish between a `DecoderError` and an error string.\n */\nexport const isDecoderError = (a: any): a is DecoderError =>\n  a.kind === 'DecoderError' && typeof a.at === 'string' && typeof a.message === 'string';\n\n/*\n * Helpers\n */\nconst isJsonArray = (json: any): json is unknown[] => Array.isArray(json);\n\nconst isJsonObject = (json: any): json is Record<string, unknown> =>\n  typeof json === 'object' && json !== null && !isJsonArray(json);\n\nconst typeString = (json: unknown): string => {\n  switch (typeof json) {\n    case 'string':\n      return 'a string';\n    case 'number':\n      return 'a number';\n    case 'boolean':\n      return 'a boolean';\n    case 'undefined':\n      return 'undefined';\n    case 'object':\n      if (json instanceof Array) {\n        return 'an array';\n      } else if (json === null) {\n        return 'null';\n      } else {\n        return 'an object';\n      }\n    default:\n      return JSON.stringify(json);\n  }\n};\n\nconst expectedGot = (expected: string, got: unknown) =>\n  `expected ${expected}, got ${typeString(got)}`;\n\nconst printPath = (paths: (string | number)[]): string =>\n  paths.map(path => (typeof path === 'string' ? `.${path}` : `[${path}]`)).join('');\n\nconst prependAt = (newAt: string, {at, ...rest}: Partial<DecoderError>): Partial<DecoderError> => ({\n  at: newAt + (at || ''),\n  ...rest\n});\n\n/**\n * Decoders transform json objects with unknown structure into known and\n * verified forms. You can create objects of type `Decoder<A>` with either the\n * primitive decoder functions, such as `boolean()` and `string()`, or by\n * applying higher-order decoders to the primitives, such as `array(boolean())`\n * or `dict(string())`.\n *\n * Each of the decoder functions are available both as a static method on\n * `Decoder` and as a function alias -- for example the string decoder is\n * defined at `Decoder.string()`, but is also aliased to `string()`. Using the\n * function aliases exported with the library is recommended.\n *\n * `Decoder` exposes a number of 'run' methods, which all decode json in the\n * same way, but communicate success and failure in different ways. The `map`\n * and `andThen` methods modify decoders without having to call a 'run' method.\n *\n * Alternatively, the main decoder `run()` method returns an object of type\n * `Result<A, DecoderError>`. This library provides a number of helper\n * functions for dealing with the `Result` type, so you can do all the same\n * things with a `Result` as with the decoder methods.\n */\nexport class Decoder<A> {\n  /**\n   * The Decoder class constructor is kept private to separate the internal\n   * `decode` function from the external `run` function. The distinction\n   * between the two functions is that `decode` returns a\n   * `Partial<DecoderError>` on failure, which contains an unfinished error\n   * report. When `run` is called on a decoder, the relevant series of `decode`\n   * calls is made, and then on failure the resulting `Partial<DecoderError>`\n   * is turned into a `DecoderError` by filling in the missing information.\n   *\n   * While hiding the constructor may seem restrictive, leveraging the\n   * provided decoder combinators and helper functions such as\n   * `andThen` and `map` should be enough to build specialized decoders as\n   * needed.\n   */\n  private constructor(private decode: (json: unknown) => DecodeResult<A>) {}\n\n  /**\n   * Decoder primitive that validates strings, and fails on all other input.\n   */\n  static string(): Decoder<string> {\n    return new Decoder<string>(\n      (json: unknown) =>\n        typeof json === 'string'\n          ? Result.ok(json)\n          : Result.err({message: expectedGot('a string', json)})\n    );\n  }\n\n  /**\n   * Decoder primitive that validates numbers, and fails on all other input.\n   */\n  static number(): Decoder<number> {\n    return new Decoder<number>(\n      (json: unknown) =>\n        typeof json === 'number'\n          ? Result.ok(json)\n          : Result.err({message: expectedGot('a number', json)})\n    );\n  }\n\n  /**\n   * Decoder primitive that validates booleans, and fails on all other input.\n   */\n  static boolean(): Decoder<boolean> {\n    return new Decoder<boolean>(\n      (json: unknown) =>\n        typeof json === 'boolean'\n          ? Result.ok(json)\n          : Result.err({message: expectedGot('a boolean', json)})\n    );\n  }\n\n  /**\n   * Escape hatch to bypass validation. Always succeeds and types the result as\n   * `any`. Useful for defining decoders incrementally, particularly for\n   * complex objects.\n   *\n   * Example:\n   * ```\n   * interface User {\n   *   name: string;\n   *   complexUserData: ComplexType;\n   * }\n   *\n   * const userDecoder: Decoder<User> = object({\n   *   name: string(),\n   *   complexUserData: anyJson()\n   * });\n   * ```\n   */\n  static anyJson = (): Decoder<any> => new Decoder<any>((json: any) => Result.ok(json));\n\n  /**\n   * Decoder identity function which always succeeds and types the result as\n   * `unknown`.\n   */\n  static unknownJson = (): Decoder<unknown> =>\n    new Decoder<unknown>((json: unknown) => Result.ok(json));\n\n  /**\n   * Decoder primitive that only matches on exact values.\n   *\n   * For primitive values and shallow structures of primitive values `constant`\n   * will infer an exact literal type:\n   * ```\n   *  | Decoder                      | Type                          |\n   *  | ---------------------------- | ------------------------------|\n   *  | constant(true)               | Decoder<true>                 |\n   *  | constant(false)              | Decoder<false>                |\n   *  | constant(null)               | Decoder<null>                 |\n   *  | constant(undefined)          | Decoder<undefined>            |\n   *  | constant('alaska')           | Decoder<'alaska'>             |\n   *  | constant(50)                 | Decoder<50>                   |\n   *  | constant([1,2,3])            | Decoder<[1,2,3]>              |\n   *  | constant({x: 't'})           | Decoder<{x: 't'}>             |\n   * ```\n   *\n   * Inference breaks on nested structures, which require an annotation to get\n   * the literal type:\n   * ```\n   *  | Decoder                      | Type                          |\n   *  | -----------------------------|-------------------------------|\n   *  | constant([1,[2]])            | Decoder<(number|number[])[]>  |\n   *  | constant<[1,[2]]>([1,[2]])   | Decoder<[1,[2]]>              |\n   *  | constant({x: [1]})           | Decoder<{x: number[]}>        |\n   *  | constant<{x: [1]}>({x: [1]}) | Decoder<{x: [1]}>             |\n   * ```\n   */\n  static constant<T extends string | number | boolean | []>(value: T): Decoder<T>;\n  static constant<T extends string | number | boolean, U extends [T, ...T[]]>(value: U): Decoder<U>;\n  static constant<T extends string | number | boolean, U extends Record<string, T>>(value: U): Decoder<U>;\n  static constant<T>(value: T): Decoder<T>;\n  static constant(value: any) {\n    return new Decoder(\n      (json: unknown) =>\n        isEqual(json, value)\n          ? Result.ok(value)\n          : Result.err({message: `expected ${JSON.stringify(value)}, got ${JSON.stringify(json)}`})\n    );\n  }\n\n  /**\n   * An higher-order decoder that runs decoders on specified fields of an object,\n   * and returns a new object with those fields. If `object` is called with no\n   * arguments, then the outer object part of the json is validated but not the\n   * contents, typing the result as a record where all keys have a value of\n   * type `unknown`.\n   *\n   * The `optional` and `constant` decoders are particularly useful for decoding\n   * objects that match typescript interfaces.\n   *\n   * To decode a single field that is inside of an object see `valueAt`.\n   *\n   * Example:\n   * ```\n   * object({x: number(), y: number()}).run({x: 5, y: 10})\n   * // => {ok: true, result: {x: 5, y: 10}}\n   *\n   * object().map(Object.keys).run({n: 1, i: [], c: {}, e: 'e'})\n   * // => {ok: true, result: ['n', 'i', 'c', 'e']}\n   * ```\n   */\n  static object(): Decoder<Record<string, unknown>>;\n  static object<A>(decoders: DecoderObject<A>): Decoder<A>;\n  static object<A>(decoders?: DecoderObject<A>) {\n    return new Decoder((json: unknown) => {\n      if (isJsonObject(json) && decoders) {\n        let obj: any = {};\n        for (const key in decoders) {\n          if (decoders.hasOwnProperty(key)) {\n            const r = decoders[key].decode(json[key]);\n            if (r.ok === true) {\n              // tslint:disable-next-line:strict-type-predicates\n              if (r.result !== undefined) {\n                obj[key] = r.result;\n              }\n            } else if (json[key] === undefined) {\n              return Result.err({message: `the key '${key}' is required but was not present`});\n            } else {\n              return Result.err(prependAt(`.${key}`, r.error));\n            }\n          }\n        }\n        return Result.ok(obj);\n      } else if (isJsonObject(json)) {\n        return Result.ok(json);\n      } else {\n        return Result.err({message: expectedGot('an object', json)});\n      }\n    });\n  }\n\n  /**\n   * Decoder for json arrays. Runs `decoder` on each array element, and succeeds\n   * if all elements are successfully decoded. If no `decoder` argument is\n   * provided then the outer array part of the json is validated but not the\n   * contents, typing the result as `unknown[]`.\n   *\n   * To decode a single value that is inside of an array see `valueAt`.\n   *\n   * Examples:\n   * ```\n   * array(number()).run([1, 2, 3])\n   * // => {ok: true, result: [1, 2, 3]}\n   *\n   * array(array(boolean())).run([[true], [], [true, false, false]])\n   * // => {ok: true, result: [[true], [], [true, false, false]]}\n   *\n   *\n   * const validNumbersDecoder = array()\n   *   .map((arr: unknown[]) => arr.map(number().run))\n   *   .map(Result.successes)\n   *\n   * validNumbersDecoder.run([1, true, 2, 3, 'five', 4, []])\n   * // {ok: true, result: [1, 2, 3, 4]}\n   *\n   * validNumbersDecoder.run([false, 'hi', {}])\n   * // {ok: true, result: []}\n   *\n   * validNumbersDecoder.run(false)\n   * // {ok: false, error: {..., message: \"expected an array, got a boolean\"}}\n   * ```\n   */\n  static array(): Decoder<unknown[]>;\n  static array<A>(decoder: Decoder<A>): Decoder<A[]>;\n  static array<A>(decoder?: Decoder<A>) {\n    return new Decoder(json => {\n      if (isJsonArray(json) && decoder) {\n        const decodeValue = (v: unknown, i: number): DecodeResult<A> =>\n          Result.mapError(err => prependAt(`[${i}]`, err), decoder.decode(v));\n\n        return json.reduce(\n          (acc: DecodeResult<A[]>, v: unknown, i: number) =>\n            Result.map2((arr, result) => [...arr, result], acc, decodeValue(v, i)),\n          Result.ok([])\n        );\n      } else if (isJsonArray(json)) {\n        return Result.ok(json);\n      } else {\n        return Result.err({message: expectedGot('an array', json)});\n      }\n    });\n  }\n\n  /**\n   * Decoder for fixed-length arrays, aka Tuples.\n   *\n   * Supports up to 8-tuples.\n   *\n   * Example:\n   * ```\n   * tuple([number(), number(), string()]).run([5, 10, 'px'])\n   * // => {ok: true, result: [5, 10, 'px']}\n   * ```\n   */\n  static tuple<A>(decoder: [Decoder<A>]): Decoder<[A]>;\n  static tuple<A, B>(decoder: [Decoder<A>, Decoder<B>]): Decoder<[A, B]>;\n  static tuple<A, B, C>(decoder: [Decoder<A>, Decoder<B>, Decoder<C>]): Decoder<[A, B, C]>;\n  static tuple<A, B, C, D>(decoder: [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>]): Decoder<[A, B, C, D]>; // prettier-ignore\n  static tuple<A, B, C, D, E>(decoder: [Decoder<A>, Decoder<B>, Decoder<C>, Decoder<D>, Decoder<E>]): Decoder<[A, B, C, D, E]>; // prettier-ignore\n  static tuple<A, 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]>; // prettier-ignore\n  static tuple<A, 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]>; // prettier-ignore\n  static tuple<A, 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]>; // prettier-ignore\n  static tuple<A>(decoders: Decoder<A>[]) {\n    return new Decoder((json: unknown) => {\n      if (isJsonArray(json)) {\n        if (json.length !== decoders.length) {\n          return Result.err({\n            message: `expected a tuple of length ${decoders.length}, got one of length ${\n              json.length\n            }`\n          });\n        }\n        const result = [];\n        for (let i: number = 0; i < decoders.length; i++) {\n          const nth = decoders[i].decode(json[i]);\n          if (nth.ok) {\n            result[i] = nth.result;\n          } else {\n            return Result.err(prependAt(`[${i}]`, nth.error));\n          }\n        }\n        return Result.ok(result);\n      } else {\n        return Result.err({message: expectedGot(`a tuple of length ${decoders.length}`, json)});\n      }\n    });\n  }\n\n  /**\n   * Decoder for json objects where the keys are unknown strings, but the values\n   * should all be of the same type.\n   *\n   * Example:\n   * ```\n   * dict(number()).run({chocolate: 12, vanilla: 10, mint: 37});\n   * // => {ok: true, result: {chocolate: 12, vanilla: 10, mint: 37}}\n   * ```\n   */\n  static dict = <A>(decoder: Decoder<A>): Decoder<Record<string, A>> =>\n    new Decoder(json => {\n      if (isJsonObject(json)) {\n        let obj: Record<string, A> = {};\n        for (const key in json) {\n          if (json.hasOwnProperty(key)) {\n            const r = decoder.decode(json[key]);\n            if (r.ok === true) {\n              obj[key] = r.result;\n            } else {\n              return Result.err(prependAt(`.${key}`, r.error));\n            }\n          }\n        }\n        return Result.ok(obj);\n      } else {\n        return Result.err({message: expectedGot('an object', json)});\n      }\n    });\n\n  /**\n   * Decoder for values that may be `undefined`. This is primarily helpful for\n   * decoding interfaces with optional fields.\n   *\n   * Example:\n   * ```\n   * interface User {\n   *   id: number;\n   *   isOwner?: boolean;\n   * }\n   *\n   * const decoder: Decoder<User> = object({\n   *   id: number(),\n   *   isOwner: optional(boolean())\n   * });\n   * ```\n   */\n  static optional = <A>(decoder: Decoder<A>): Decoder<undefined | A> =>\n    new Decoder<undefined | A>(\n      (json: unknown) => (json === undefined ? Result.ok(undefined) : decoder.decode(json))\n    );\n\n  /**\n   * Decoder that attempts to run each decoder in `decoders` and either succeeds\n   * with the first successful decoder, or fails after all decoders have failed.\n   *\n   * Note that `oneOf` expects the decoders to all have the same return type,\n   * while `union` creates a decoder for the union type of all the input\n   * decoders.\n   *\n   * Examples:\n   * ```\n   * oneOf(string(), number().map(String))\n   * oneOf(constant('start'), constant('stop'), succeed('unknown'))\n   * ```\n   */\n  static oneOf = <A>(...decoders: Decoder<A>[]): Decoder<A> =>\n    new Decoder<A>((json: unknown) => {\n      const errors: Partial<DecoderError>[] = [];\n      for (let i: number = 0; i < decoders.length; i++) {\n        const r = decoders[i].decode(json);\n        if (r.ok === true) {\n          return r;\n        } else {\n          errors[i] = r.error;\n        }\n      }\n      const errorsList = errors\n        .map(error => `at error${error.at || ''}: ${error.message}`)\n        .join('\", \"');\n      return Result.err({\n        message: `expected a value matching one of the decoders, got the errors [\"${errorsList}\"]`\n      });\n    });\n\n  /**\n   * Combines 2-8 decoders of disparate types into a decoder for the union of all\n   * the types.\n   *\n   * If you need more than 8 variants for your union, it's possible to use\n   * `oneOf` in place of `union` as long as you annotate every decoder with the\n   * union type.\n   *\n   * Example:\n   * ```\n   * type C = {a: string} | {b: number};\n   *\n   * const unionDecoder: Decoder<C> = union(object({a: string()}), object({b: number()}));\n   * const oneOfDecoder: Decoder<C> = oneOf(object<C>({a: string()}), object<C>({b: number()}));\n   * ```\n   */\n  static union <A, B>(ad: Decoder<A>, bd: Decoder<B>): Decoder<A | B>; // prettier-ignore\n  static union <A, B, C>(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>): Decoder<A | B | C>; // prettier-ignore\n  static union <A, B, C, D>(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>): Decoder<A | B | C | D>; // prettier-ignore\n  static union <A, 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>; // prettier-ignore\n  static union <A, 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>; // prettier-ignore\n  static union <A, 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>; // prettier-ignore\n  static union <A, 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>; // prettier-ignore\n  static union(ad: Decoder<any>, bd: Decoder<any>, ...decoders: Decoder<any>[]): Decoder<any> {\n    return Decoder.oneOf(ad, bd, ...decoders);\n  }\n\n  /**\n   * Combines 2-8 object decoders into a decoder for the intersection of all the objects.\n   *\n   * Example:\n   * ```\n   * interface Pet {\n   *   name: string;\n   *   maxLegs: number;\n   * }\n   *\n   * interface Cat extends Pet {\n   *   evil: boolean;\n   * }\n   *\n   * const petDecoder: Decoder<Pet> = object({name: string(), maxLegs: number()});\n   * const catDecoder: Decoder<Cat> = intersection(petDecoder, object({evil: boolean()}));\n   * ```\n   */\n  static intersection <A, B>(ad: Decoder<A>, bd: Decoder<B>): Decoder<A & B>; // prettier-ignore\n  static intersection <A, B, C>(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>): Decoder<A & B & C>; // prettier-ignore\n  static intersection <A, B, C, D>(ad: Decoder<A>, bd: Decoder<B>, cd: Decoder<C>, dd: Decoder<D>): Decoder<A & B & C & D>; // prettier-ignore\n  static intersection <A, 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>; // prettier-ignore\n  static intersection <A, 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>; // prettier-ignore\n  static intersection <A, 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>; // prettier-ignore\n  static intersection <A, 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>; // prettier-ignore\n  static intersection(ad: Decoder<any>, bd: Decoder<any>, ...ds: Decoder<any>[]): Decoder<any> {\n    return new Decoder((json: unknown) =>\n      [ad, bd, ...ds].reduce(\n        (acc: DecodeResult<any>, decoder) => Result.map2(Object.assign, acc, decoder.decode(json)),\n        Result.ok({})\n      )\n    );\n  }\n\n  /**\n   * Decoder that always succeeds with either the decoded value, or a fallback\n   * default value.\n   */\n  static withDefault = <A>(defaultValue: A, decoder: Decoder<A>): Decoder<A> =>\n    new Decoder<A>((json: unknown) =>\n      Result.ok(Result.withDefault(defaultValue, decoder.decode(json)))\n    );\n\n  /**\n   * Decoder that pulls a specific field out of a json structure, instead of\n   * decoding and returning the full structure. The `paths` array describes the\n   * object keys and array indices to traverse, so that values can be pulled out\n   * of a nested structure.\n   *\n   * Example:\n   * ```\n   * const decoder = valueAt(['a', 'b', 0], string());\n   *\n   * decoder.run({a: {b: ['surprise!']}})\n   * // => {ok: true, result: 'surprise!'}\n   *\n   * decoder.run({a: {x: 'cats'}})\n   * // => {ok: false, error: {... at: 'input.a.b[0]' message: 'path does not exist'}}\n   * ```\n   *\n   * Note that the `decoder` is ran on the value found at the last key in the\n   * path, even if the last key is not found. This allows the `optional`\n   * decoder to succeed when appropriate.\n   * ```\n   * const optionalDecoder = valueAt(['a', 'b', 'c'], optional(string()));\n   *\n   * optionalDecoder.run({a: {b: {c: 'surprise!'}}})\n   * // => {ok: true, result: 'surprise!'}\n   *\n   * optionalDecoder.run({a: {b: 'cats'}})\n   * // => {ok: false, error: {... at: 'input.a.b.c' message: 'expected an object, got \"cats\"'}\n   *\n   * optionalDecoder.run({a: {b: {z: 1}}})\n   * // => {ok: true, result: undefined}\n   * ```\n   */\n  static valueAt = <A>(paths: (string | number)[], decoder: Decoder<A>): Decoder<A> =>\n    new Decoder<A>((json: unknown) => {\n      let jsonAtPath: any = json;\n      for (let i: number = 0; i < paths.length; i++) {\n        if (jsonAtPath === undefined) {\n          return Result.err({\n            at: printPath(paths.slice(0, i + 1)),\n            message: 'path does not exist'\n          });\n        } else if (typeof paths[i] === 'string' && !isJsonObject(jsonAtPath)) {\n          return Result.err({\n            at: printPath(paths.slice(0, i + 1)),\n            message: expectedGot('an object', jsonAtPath)\n          });\n        } else if (typeof paths[i] === 'number' && !isJsonArray(jsonAtPath)) {\n          return Result.err({\n            at: printPath(paths.slice(0, i + 1)),\n            message: expectedGot('an array', jsonAtPath)\n          });\n        } else {\n          jsonAtPath = jsonAtPath[paths[i]];\n        }\n      }\n      return Result.mapError(\n        error =>\n          jsonAtPath === undefined\n            ? {at: printPath(paths), message: 'path does not exist'}\n            : prependAt(printPath(paths), error),\n        decoder.decode(jsonAtPath)\n      );\n    });\n\n  /**\n   * Decoder that ignores the input json and always succeeds with `fixedValue`.\n   */\n  static succeed = <A>(fixedValue: A): Decoder<A> =>\n    new Decoder<A>((json: unknown) => Result.ok(fixedValue));\n\n  /**\n   * Decoder that ignores the input json and always fails with `errorMessage`.\n   */\n  static fail = <A>(errorMessage: string): Decoder<A> =>\n    new Decoder<A>((json: unknown) => Result.err({message: errorMessage}));\n\n  /**\n   * Decoder that allows for validating recursive data structures. Unlike with\n   * functions, decoders assigned to variables can't reference themselves\n   * before they are fully defined. We can avoid prematurely referencing the\n   * decoder by wrapping it in a function that won't be called until use, at\n   * which point the decoder has been defined.\n   *\n   * Example:\n   * ```\n   * interface Comment {\n   *   msg: string;\n   *   replies: Comment[];\n   * }\n   *\n   * const decoder: Decoder<Comment> = object({\n   *   msg: string(),\n   *   replies: lazy(() => array(decoder))\n   * });\n   * ```\n   */\n  static lazy = <A>(mkDecoder: () => Decoder<A>): Decoder<A> =>\n    new Decoder((json: unknown) => mkDecoder().decode(json));\n\n  /**\n   * Run the decoder and return a `Result` with either the decoded value or a\n   * `DecoderError` containing the json input, the location of the error, and\n   * the error message.\n   *\n   * Examples:\n   * ```\n   * number().run(12)\n   * // => {ok: true, result: 12}\n   *\n   * string().run(9001)\n   * // =>\n   * // {\n   * //   ok: false,\n   * //   error: {\n   * //     kind: 'DecoderError',\n   * //     input: 9001,\n   * //     at: 'input',\n   * //     message: 'expected a string, got 9001'\n   * //   }\n   * // }\n   * ```\n   */\n  run = (json: unknown): RunResult<A> =>\n    Result.mapError(\n      error => ({\n        kind: 'DecoderError' as 'DecoderError',\n        input: json,\n        at: 'input' + (error.at || ''),\n        message: error.message || ''\n      }),\n      this.decode(json)\n    );\n\n  /**\n   * Run the decoder as a `Promise`.\n   */\n  runPromise = (json: unknown): Promise<A> => Result.asPromise(this.run(json));\n\n  /**\n   * Run the decoder and return the value on success, or throw an exception\n   * with a formatted error string.\n   */\n  runWithException = (json: unknown): A => Result.withException(this.run(json));\n\n  /**\n   * Construct a new decoder that applies a transformation to the decoded\n   * result. If the decoder succeeds then `f` will be applied to the value. If\n   * it fails the error will propagated through.\n   *\n   * Example:\n   * ```\n   * number().map(x => x * 5).run(10)\n   * // => {ok: true, result: 50}\n   * ```\n   */\n  map = <B>(f: (value: A) => B): Decoder<B> =>\n    new Decoder<B>((json: unknown) => Result.map(f, this.decode(json)));\n\n  /**\n   * Chain together a sequence of decoders. The first decoder will run, and\n   * then the function will determine what decoder to run second. If the result\n   * of the first decoder succeeds then `f` will be applied to the decoded\n   * value. If it fails the error will propagate through.\n   *\n   * This is a very powerful method -- it can act as both the `map` and `where`\n   * methods, can improve error messages for edge cases, and can be used to\n   * make a decoder for custom types.\n   *\n   * Example of adding an error message:\n   * ```\n   * const versionDecoder = valueAt(['version'], number());\n   * const infoDecoder3 = object({a: boolean()});\n   *\n   * const decoder = versionDecoder.andThen(version => {\n   *   switch (version) {\n   *     case 3:\n   *       return infoDecoder3;\n   *     default:\n   *       return fail(`Unable to decode info, version ${version} is not supported.`);\n   *   }\n   * });\n   *\n   * decoder.run({version: 3, a: true})\n   * // => {ok: true, result: {a: true}}\n   *\n   * decoder.run({version: 5, x: 'abc'})\n   * // =>\n   * // {\n   * //   ok: false,\n   * //   error: {... message: 'Unable to decode info, version 5 is not supported.'}\n   * // }\n   * ```\n   *\n   * Example of decoding a custom type:\n   * ```\n   * // nominal type for arrays with a length of at least one\n   * type NonEmptyArray<T> = T[] & { __nonEmptyArrayBrand__: void };\n   *\n   * const nonEmptyArrayDecoder = <T>(values: Decoder<T>): Decoder<NonEmptyArray<T>> =>\n   *   array(values).andThen(arr =>\n   *     arr.length > 0\n   *       ? succeed(createNonEmptyArray(arr))\n   *       : fail(`expected a non-empty array, got an empty array`)\n   *   );\n   * ```\n   */\n  andThen = <B>(f: (value: A) => Decoder<B>): Decoder<B> =>\n    new Decoder<B>((json: unknown) =>\n      Result.andThen(value => f(value).decode(json), this.decode(json))\n    );\n\n  /**\n   * Add constraints to a decoder _without_ changing the resulting type. The\n   * `test` argument is a predicate function which returns true for valid\n   * inputs. When `test` fails on an input, the decoder fails with the given\n   * `errorMessage`.\n   *\n   * ```\n   * const chars = (length: number): Decoder<string> =>\n   *   string().where(\n   *     (s: string) => s.length === length,\n   *     `expected a string of length ${length}`\n   *   );\n   *\n   * chars(5).run('12345')\n   * // => {ok: true, result: '12345'}\n   *\n   * chars(2).run('HELLO')\n   * // => {ok: false, error: {... message: 'expected a string of length 2'}}\n   *\n   * chars(12).run(true)\n   * // => {ok: false, error: {... message: 'expected a string, got a boolean'}}\n   * ```\n   */\n  where = (test: (value: A) => boolean, errorMessage: string): Decoder<A> =>\n    this.andThen((value: A) => (test(value) ? Decoder.succeed(value) : Decoder.fail(errorMessage)));\n}\n"
  },
  {
    "path": "src/index.ts",
    "content": "import * as Result from './result';\nexport {Result};\n\nexport {Decoder, DecoderError, isDecoderError, DecoderObject} from './decoder';\n\nexport {\n  string,\n  number,\n  boolean,\n  anyJson,\n  unknownJson,\n  constant,\n  object,\n  array,\n  tuple,\n  dict,\n  optional,\n  oneOf,\n  union,\n  intersection,\n  withDefault,\n  valueAt,\n  succeed,\n  fail,\n  lazy\n} from './combinators';\n"
  },
  {
    "path": "src/result.ts",
    "content": "/**\n * The result of a computation that may fail. The decoding function\n * `Decoder.run` returns a `Result`. The value of a `Result` is either `Ok` if\n * the computation succeeded, or `Err` if there was some failure in the\n * process.\n */\nexport type Result<V, E> = Ok<V> | Err<E>;\n\n/**\n * The success type variant for `Result`. Denotes that a result value was\n * computed with no errors.\n */\nexport interface Ok<V> {\n  ok: true;\n  result: V;\n}\n\n/**\n * The error type variant for `Result`. Denotes that some error occurred before\n * the result was computed.\n */\nexport interface Err<E> {\n  ok: false;\n  error: E;\n}\n\n/**\n * Wraps values in an `Ok` type.\n *\n * Example: `ok(5) // => {ok: true, result: 5}`\n */\nexport const ok = <V>(result: V): Ok<V> => ({ok: true, result: result});\n\n/**\n * Typeguard for `Ok`.\n */\nexport const isOk = <V>(r: Result<V, any>): r is Ok<V> => r.ok === true;\n\n/**\n * Wraps errors in an `Err` type.\n *\n * Example: `err('on fire') // => {ok: false, error: 'on fire'}`\n */\nexport const err = <E>(error: E): Err<E> => ({ok: false, error: error});\n\n/**\n * Typeguard for `Err`.\n */\nexport const isErr = <E>(r: Result<any, E>): r is Err<E> => r.ok === false;\n\n/**\n * Create a `Promise` that either resolves with the result of `Ok` or rejects\n * with the error of `Err`.\n */\nexport const asPromise = <V>(r: Result<V, any>): Promise<V> =>\n  r.ok === true ? Promise.resolve(r.result) : Promise.reject(r.error);\n\n/**\n * Unwraps a `Result` and returns either the result of an `Ok`, or\n * `defaultValue`.\n *\n * Example:\n * ```\n * Result.withDefault(5, number().run(json))\n * ```\n *\n * It would be nice if `Decoder` had an instance method that mirrored this\n * function. Such a method would look something like this:\n * ```\n * class Decoder<A> {\n *   runWithDefault = (defaultValue: A, json: any): A =>\n *     Result.withDefault(defaultValue, this.run(json));\n * }\n *\n * number().runWithDefault(5, json)\n * ```\n * Unfortunately, the type of `defaultValue: A` on the method causes issues\n * with type inference on  the `object` decoder in some situations. While these\n * inference issues can be solved by providing the optional type argument for\n * `object`s, the extra trouble and confusion doesn't seem worth it.\n */\nexport const withDefault = <V>(defaultValue: V, r: Result<V, any>): V =>\n  r.ok === true ? r.result : defaultValue;\n\n/**\n * Return the successful result, or throw an error.\n */\nexport const withException = <V>(r: Result<V, any>): V => {\n  if (r.ok === true) {\n    return r.result;\n  } else {\n    throw r.error;\n  }\n};\n\n/**\n * Given an array of `Result`s, return the successful values.\n */\nexport const successes = <A>(results: Result<A, any>[]): A[] =>\n  results.reduce((acc: A[], r: Result<A, any>) => (r.ok === true ? acc.concat(r.result) : acc), []);\n\n/**\n * Apply `f` to the result of an `Ok`, or pass the error through.\n */\nexport const map = <A, B, E>(f: (value: A) => B, r: Result<A, E>): Result<B, E> =>\n  r.ok === true ? ok<B>(f(r.result)) : r;\n\n/**\n * Apply `f` to the result of two `Ok`s, or pass an error through. If both\n * `Result`s are errors then the first one is returned.\n */\nexport const map2 = <A, B, C, E>(f: (av: A, bv: B) => C, ar: Result<A, E>, br: Result<B, E>): Result<C, E> =>\n  ar.ok === false ? ar :\n    br.ok === false ? br :\n      ok<C>(f(ar.result, br.result));\n\n/**\n * Apply `f` to the error of an `Err`, or pass the success through.\n */\nexport const mapError = <V, A, B>(f: (error: A) => B, r: Result<V, A>): Result<V, B> =>\n  r.ok === true ? r : err<B>(f(r.error));\n\n/**\n * Chain together a sequence of computations that may fail, similar to a\n * `Promise`. If the first computation fails then the error will propagate\n * through. If it succeeds, then `f` will be applied to the value, returning a\n * new `Result`.\n */\nexport const andThen = <A, B, E>(f: (value: A) => Result<B, E>, r: Result<A, E>): Result<B, E> =>\n  r.ok === true ? f(r.result) : r;\n"
  },
  {
    "path": "test/json-decode.test.ts",
    "content": "import {\n  Decoder,\n  Result,\n  isDecoderError,\n  string,\n  number,\n  boolean,\n  anyJson,\n  unknownJson,\n  constant,\n  object,\n  array,\n  dict,\n  optional,\n  oneOf,\n  union,\n  intersection,\n  withDefault,\n  valueAt,\n  succeed,\n  tuple,\n  fail,\n  lazy\n} from '../src/index';\n\ndescribe('string', () => {\n  const decoder = string();\n\n  it('succeeds when given a string', () => {\n    expect(decoder.run('hey')).toEqual({ok: true, result: 'hey'});\n  });\n\n  it('fails when given a number', () => {\n    expect(decoder.run(1)).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected a string, got a number'}\n    });\n  });\n\n  it('fails when given null', () => {\n    expect(decoder.run(null)).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected a string, got null'}\n    });\n  });\n\n  it('fails when given a boolean', () => {\n    expect(decoder.run(true)).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected a string, got a boolean'}\n    });\n  });\n});\n\ndescribe('number', () => {\n  const decoder = number();\n\n  it('succeeds when given a number', () => {\n    expect(decoder.run(5)).toEqual({ok: true, result: 5});\n  });\n\n  it('fails when given a string', () => {\n    expect(decoder.run('hey')).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected a number, got a string'}\n    });\n  });\n\n  it('fails when given boolean', () => {\n    expect(decoder.run(true)).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected a number, got a boolean'}\n    });\n  });\n});\n\ndescribe('boolean', () => {\n  const decoder = boolean();\n\n  it('succeeds when given a boolean', () => {\n    expect(decoder.run(true)).toEqual({ok: true, result: true});\n  });\n\n  it('fails when given a string', () => {\n    expect(decoder.run('hey')).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected a boolean, got a string'}\n    });\n  });\n\n  it('fails when given a number', () => {\n    expect(decoder.run(1)).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected a boolean, got a number'}\n    });\n  });\n});\n\ndescribe('anyJson', () => {\n  it('bypasses type validation', () => {\n    // in a real use case this could be a deeply nested object\n    type ComplexType = number;\n\n    interface User {\n      name: string;\n      complexUserData: ComplexType;\n    }\n\n    const userDecoder: Decoder<User> = object({\n      name: string(),\n      complexUserData: anyJson()\n    });\n\n    expect(userDecoder.run({name: 'Wanda', complexUserData: true})).toEqual({\n      ok: true,\n      result: {name: 'Wanda', complexUserData: true}\n    });\n\n    expect(userDecoder.run({name: 'Willard', complexUserData: 'trash data'})).toEqual({\n      ok: true,\n      result: {name: 'Willard', complexUserData: 'trash data'}\n    });\n\n    expect(userDecoder.run({name: 73, complexUserData: []})).toMatchObject({\n      ok: false,\n      error: {at: 'input.name', message: 'expected a string, got a number'}\n    });\n  });\n});\n\ndescribe('unknownJson', () => {\n  it('accepts any values', () => {\n    expect(unknownJson().run(1)).toEqual({ok: true, result: 1});\n    expect(unknownJson().run(false)).toEqual({ok: true, result: false});\n    expect(unknownJson().run({boots: 'n cats'})).toEqual({ok: true, result: {boots: 'n cats'}});\n  });\n});\n\ndescribe('constant', () => {\n  it('works for string-literals', () => {\n    const decoder: Decoder<'zero'> = constant('zero');\n\n    expect(decoder.run('zero')).toEqual({ok: true, result: 'zero'});\n  });\n\n  it('fails when given two different values', () => {\n    const decoder: Decoder<42> = constant(42);\n\n    expect(decoder.run(true)).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected 42, got true'}\n    });\n  });\n\n  it('can decode the true-literal type', () => {\n    interface TrueValue {\n      x: true;\n    }\n    const decoder: Decoder<TrueValue> = object({x: constant(true)});\n\n    expect(decoder.run({x: true})).toEqual({ok: true, result: {x: true}});\n  });\n\n  it('can decode the false-literal type', () => {\n    interface FalseValue {\n      x: false;\n    }\n    const decoder: Decoder<FalseValue> = object({x: constant(false)});\n\n    expect(decoder.run({x: false})).toEqual({ok: true, result: {x: false}});\n  });\n\n  it('can decode the null-literal type', () => {\n    interface NullValue {\n      x: null;\n    }\n    const decoder: Decoder<NullValue> = object({x: constant(null)});\n\n    expect(decoder.run({x: null})).toEqual({ok: true, result: {x: null}});\n  });\n\n  it('can decode a constant array', () => {\n    const decoder: Decoder<[1, 2, 3]> = constant([1, 2, 3]);\n\n    expect(decoder.run([1, 2, 3])).toEqual({ok: true, result: [1, 2, 3]});\n    expect(decoder.run([1, 2, 3, 4])).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected [1,2,3], got [1,2,3,4]'}\n    });\n  });\n\n  it('can decode a constant object', () => {\n    const decoder: Decoder<{a: true; b: 12}> = constant({a: true, b: 12});\n\n    expect(decoder.run({a: true, b: 12})).toEqual({ok: true, result: {a: true, b: 12}});\n    expect(decoder.run({a: true, b: 7})).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected {\"a\":true,\"b\":12}, got {\"a\":true,\"b\":7}'}\n    });\n  });\n});\n\ndescribe('object', () => {\n  describe('when given valid JSON', () => {\n    it('can decode a simple object', () => {\n      const decoder = object({x: number()});\n\n      expect(decoder.run({x: 5})).toMatchObject({ok: true, result: {x: 5}});\n    });\n\n    it('can decode a nested object', () => {\n      const decoder = object({\n        payload: object({x: number(), y: number()}),\n        error: constant(false)\n      });\n      const json = {payload: {x: 5, y: 2}, error: false};\n\n      expect(decoder.run(json)).toEqual({ok: true, result: json});\n    });\n  });\n\n  describe('when given incorrect JSON', () => {\n    it('fails when not given an object', () => {\n      const decoder = object({x: number()});\n\n      expect(decoder.run('true')).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: 'expected an object, got a string'}\n      });\n    });\n\n    it('fails when given an array', () => {\n      const decoder = object({x: number()});\n\n      expect(decoder.run([])).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: 'expected an object, got an array'}\n      });\n    });\n\n    it('reports a missing key', () => {\n      const decoder = object({x: number()});\n\n      expect(decoder.run({})).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: \"the key 'x' is required but was not present\"}\n      });\n    });\n\n    it('reports invalid values', () => {\n      const decoder = object({name: string()});\n\n      expect(decoder.run({name: 5})).toMatchObject({\n        ok: false,\n        error: {at: 'input.name', message: 'expected a string, got a number'}\n      });\n    });\n\n    it('properly displays nested errors', () => {\n      const decoder = object({\n        hello: object({\n          hey: object({\n            'Howdy!': string()\n          })\n        })\n      });\n\n      const error = decoder.run({hello: {hey: {'Howdy!': {}}}});\n      expect(error).toMatchObject({\n        ok: false,\n        error: {at: 'input.hello.hey.Howdy!', message: 'expected a string, got an object'}\n      });\n    });\n  });\n\n  it('ignores optional fields that decode to undefined', () => {\n    const decoder = object({\n      a: number(),\n      b: optional(string())\n    });\n\n    expect(decoder.run({a: 12, b: 'hats'})).toEqual({ok: true, result: {a: 12, b: 'hats'}});\n    expect(decoder.run({a: 12})).toEqual({ok: true, result: {a: 12}});\n  });\n\n  it('decodes any object when the object shape is not specified', () => {\n    const objectKeysDecoder: Decoder<string[]> = object().map(Object.keys);\n\n    expect(objectKeysDecoder.run({n: 1, i: [], c: {}, e: 'e'})).toEqual({\n      ok: true,\n      result: ['n', 'i', 'c', 'e']\n    });\n  });\n});\n\ndescribe('array', () => {\n  const decoder = array(number());\n\n  it('works when given an array', () => {\n    expect(decoder.run([1, 2, 3])).toEqual({ok: true, result: [1, 2, 3]});\n  });\n\n  it('fails when given something other than a array', () => {\n    expect(decoder.run('oops')).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: 'expected an array, got a string'}\n    });\n  });\n\n  describe('when given something other than an array', () => {\n    it('fails when the elements are of the wrong type', () => {\n      expect(decoder.run(['dang'])).toMatchObject({\n        ok: false,\n        error: {at: 'input[0]', message: 'expected a number, got a string'}\n      });\n    });\n\n    it('properly displays nested errors', () => {\n      const nestedDecoder = array(array(array(number())));\n\n      expect(nestedDecoder.run([[], [], [[1, 2, 3, false]]])).toMatchObject({\n        ok: false,\n        error: {at: 'input[2][0][3]', message: 'expected a number, got a boolean'}\n      });\n    });\n  });\n\n  it('decodes any array when the array members decoder is not specified', () => {\n    const validNumbersDecoder = array()\n      .map((arr: unknown[]) => arr.map(number().run))\n      .map(Result.successes);\n\n    expect(validNumbersDecoder.run([1, true, 2, 3, 'five', 4, []])).toEqual({\n      ok: true,\n      result: [1, 2, 3, 4]\n    });\n\n    expect(validNumbersDecoder.run([false, 'hi', {}])).toEqual({ok: true, result: []});\n\n    expect(validNumbersDecoder.run(false)).toMatchObject({\n      ok: false,\n      error: {message: 'expected an array, got a boolean'}\n    });\n  });\n});\n\ndescribe('tuple', () => {\n  describe('when given valid JSON', () => {\n    it('can decode a simple tuple', () => {\n      const decoder: Decoder<[number, number]> = tuple([number(), number()]);\n\n      expect(decoder.run([5, 6])).toMatchObject({ok: true, result: [5, 6]});\n    });\n\n    it('can decode tuples of mixed types', () => {\n      const decoder: Decoder<[number, string]> = tuple([number(), string()]);\n\n      expect(decoder.run([1, 'a'])).toMatchObject({ok: true, result: [1, 'a']});\n    });\n\n    it('can decode a nested object', () => {\n      const decoder: Decoder<[{x: number; y: number}, false]> = tuple([\n        object({x: number(), y: number()}),\n        constant(false)\n      ]);\n      const json = [{x: 5, y: 2}, false];\n\n      expect(decoder.run(json)).toEqual({ok: true, result: json});\n    });\n  });\n\n  describe('when given incorrect JSON', () => {\n    it('fails when the array length does not match', () => {\n      const decoder: Decoder<[number]> = tuple([number()]);\n\n      expect(decoder.run([1, 2])).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: 'expected a tuple of length 1, got one of length 2'}\n      });\n    });\n\n    it('fails when given an object', () => {\n      const decoder: Decoder<[number]> = tuple([number()]);\n\n      expect(decoder.run({x: 1})).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: 'expected a tuple of length 1, got an object'}\n      });\n    });\n\n    it('reports invalid values', () => {\n      const decoder: Decoder<[number, string]> = tuple([number(), string()]);\n\n      expect(decoder.run([4, 5])).toMatchObject({\n        ok: false,\n        error: {at: 'input[1]', message: 'expected a string, got a number'}\n      });\n    });\n\n    it('properly displays nested errors', () => {\n      const decoder: Decoder<[{hey: {'Howdy!': string}}]> = tuple([\n        object({\n          hey: object({\n            'Howdy!': string()\n          })\n        })\n      ]);\n\n      const error = decoder.run([{hey: {'Howdy!': {}}}]);\n      expect(error).toMatchObject({\n        ok: false,\n        error: {at: 'input[0].hey.Howdy!', message: 'expected a string, got an object'}\n      });\n    });\n  });\n});\n\ndescribe('dict', () => {\n  describe('with a simple value decoder', () => {\n    const decoder = dict(number());\n\n    it('can decode an empty object', () => {\n      expect(decoder.run({})).toEqual({ok: true, result: {}});\n    });\n\n    it('can decode an object of with arbitrary keys', () => {\n      expect(decoder.run({a: 1, b: 2})).toEqual({ok: true, result: {a: 1, b: 2}});\n    });\n\n    it('fails if a value cannot be decoded', () => {\n      expect(decoder.run({oh: 'no'})).toMatchObject({\n        ok: false,\n        error: {at: 'input.oh', message: 'expected a number, got a string'}\n      });\n    });\n\n    it('fails if given an array', () => {\n      expect(decoder.run([])).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: 'expected an object, got an array'}\n      });\n    });\n\n    it('fails if given a primitive', () => {\n      expect(decoder.run(5)).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: 'expected an object, got a number'}\n      });\n    });\n  });\n\n  describe('given a transformative value decoder', () => {\n    const decoder = dict(string().map(str => str + '!'));\n\n    it('transforms the values', () => {\n      expect(decoder.run({hey: 'there', yo: 'dude'})).toEqual({\n        ok: true,\n        result: {hey: 'there!', yo: 'dude!'}\n      });\n    });\n  });\n});\n\ndescribe('optional', () => {\n  describe('decoding a non-object type', () => {\n    const decoder = optional(number());\n\n    it('can decode the given type', () => {\n      expect(decoder.run(5)).toEqual({ok: true, result: 5});\n    });\n\n    it('can decode undefined', () => {\n      expect(decoder.run(undefined)).toEqual({ok: true, result: undefined});\n    });\n\n    it('fails when the value is invalid', () => {\n      expect(decoder.run(false)).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: 'expected a number, got a boolean'}\n      });\n    });\n  });\n\n  describe('decoding an interface with optional fields', () => {\n    interface User {\n      id: number;\n      isDog?: boolean;\n    }\n\n    const decoder: Decoder<User> = object({\n      id: number(),\n      isDog: optional(boolean())\n    });\n\n    it('can decode the object when the optional field is present', () => {\n      expect(decoder.run({id: 1, isDog: true})).toEqual({ok: true, result: {id: 1, isDog: true}});\n    });\n\n    it('can decode the object when the optional field is missing', () => {\n      expect(decoder.run({id: 2})).toEqual({ok: true, result: {id: 2}});\n    });\n\n    it('fails when the optional field is invalid', () => {\n      const error = decoder.run({id: 3, isDog: 'supdog'});\n      expect(error).toMatchObject({\n        ok: false,\n        error: {at: 'input.isDog', message: 'expected a boolean, got a string'}\n      });\n    });\n  });\n});\n\ndescribe('oneOf', () => {\n  describe('when given valid input', () => {\n    it('can decode a value with a single alternative', () => {\n      const decoder = oneOf(string());\n\n      expect(decoder.run('yo')).toEqual({ok: true, result: 'yo'});\n    });\n\n    it('can decode a value with multiple alternatives', () => {\n      const decoder = array(oneOf(string().map(s => s.length), number()));\n\n      expect(decoder.run(['hey', 10])).toEqual({ok: true, result: [3, 10]});\n    });\n  });\n\n  it('fails when a value does not match any decoder', () => {\n    const decoder = oneOf(string(), number().map(String));\n\n    expect(decoder.run([])).toMatchObject({\n      ok: false,\n      error: {\n        at: 'input',\n        message:\n          'expected a value matching one of the decoders, got the errors ' +\n          '[\"at error: expected a string, got an array\", \"at error: expected a number, got an array\"]'\n      }\n    });\n  });\n\n  it('fails and reports errors for nested values', () => {\n    const decoder = array(\n      oneOf(valueAt([1, 'a', 'b'], number()), valueAt([1, 'a', 'x'], number()))\n    );\n\n    expect(decoder.run([[{}, {a: {b: true}}]])).toMatchObject({\n      ok: false,\n      error: {\n        at: 'input[0]',\n        message:\n          'expected a value matching one of the decoders, got the errors ' +\n          '[\"at error[1].a.b: expected a number, got a boolean\", ' +\n          '\"at error[1].a.x: path does not exist\"]'\n      }\n    });\n  });\n\n  it('can act as the union function when given the correct annotation', () => {\n    type C = {a: string} | {b: number};\n\n    const decoder: Decoder<C> = oneOf(object<C>({a: string()}), object<C>({b: number()}));\n\n    expect(decoder.run({a: 'xyz'})).toEqual({ok: true, result: {a: 'xyz'}});\n  });\n});\n\ndescribe('union', () => {\n  interface A {\n    kind: 'a';\n    value: number;\n  }\n  interface B {\n    kind: 'b';\n    value: boolean;\n  }\n  type C = A | B;\n\n  const decoder: Decoder<C> = union(\n    object({kind: constant('a'), value: number()}),\n    object({kind: constant('b'), value: boolean()})\n  );\n\n  it('can decode a value that matches one of the union types', () => {\n    const json = {kind: 'a', value: 12};\n    expect(decoder.run(json)).toEqual({ok: true, result: json});\n  });\n\n  it('fails when a value does not match any decoders', () => {\n    const error = decoder.run({kind: 'b', value: 12});\n    expect(error).toMatchObject({\n      ok: false,\n      error: {\n        at: 'input',\n        message:\n          'expected a value matching one of the decoders, got the errors ' +\n          '[\"at error.kind: expected \"a\", got \"b\"\", \"at error.value: expected a boolean, got a number\"]'\n      }\n    });\n  });\n});\n\ndescribe('intersection', () => {\n  it('uses two decoders to decode an extended interface', () => {\n    interface A {\n      a: number;\n    }\n\n    interface AB extends A {\n      b: string;\n    }\n\n    const aDecoder: Decoder<A> = object({a: number()});\n    const abDecoder: Decoder<AB> = intersection(aDecoder, object({b: string()}));\n\n    expect(abDecoder.run({a: 12, b: '!!!'})).toEqual({ok: true, result: {a: 12, b: '!!!'}});\n  });\n\n  it('can combine many decoders', () => {\n    interface UVWXYZ {\n      u: true;\n      v: string[];\n      w: boolean | null;\n      x: number;\n      y: string;\n      z: boolean;\n    }\n\n    const uvwxyzDecoder: Decoder<UVWXYZ> = intersection(\n      object({u: constant(true)}),\n      object({v: array(string())}),\n      object({w: union(boolean(), constant(null))}),\n      object({x: number()}),\n      object({y: string(), z: boolean()})\n    );\n\n    expect(uvwxyzDecoder.run({u: true, v: [], w: null, x: 4, y: 'y', z: false})).toEqual({\n      ok: true,\n      result: {u: true, v: [], w: null, x: 4, y: 'y', z: false}\n    });\n  });\n});\n\ndescribe('withDefault', () => {\n  const decoder = withDefault('puppies', string());\n\n  it('uses the json value when decoding is successful', () => {\n    expect(decoder.run('pancakes')).toEqual({ok: true, result: 'pancakes'});\n  });\n\n  it('uses the default when the decoder fails', () => {\n    expect(decoder.run(5)).toEqual({ok: true, result: 'puppies'});\n  });\n});\n\ndescribe('valueAt', () => {\n  describe('decode an value', () => {\n    it('can decode a single object field', () => {\n      const decoder = valueAt(['a'], string());\n      expect(decoder.run({a: 'boots', b: 'cats'})).toEqual({ok: true, result: 'boots'});\n    });\n\n    it('can decode a single array value', () => {\n      const decoder = valueAt([1], string());\n      expect(decoder.run(['boots', 'cats'])).toEqual({ok: true, result: 'cats'});\n    });\n  });\n\n  describe('decode a nested path', () => {\n    const decoder = valueAt(['a', 1, 'b'], string());\n\n    it('can decode a field in a nested structure', () => {\n      expect(decoder.run({a: [{}, {b: 'surprise!'}]})).toEqual({ok: true, result: 'surprise!'});\n    });\n\n    it('fails when an array path does not exist', () => {\n      expect(decoder.run({a: []})).toMatchObject({\n        ok: false,\n        error: {at: 'input.a[1].b', message: 'path does not exist'}\n      });\n    });\n\n    it('fails when an object path does not exist', () => {\n      expect(decoder.run({x: 12})).toMatchObject({\n        ok: false,\n        error: {at: 'input.a[1]', message: 'path does not exist'}\n      });\n    });\n\n    it('fails when the decoder fails at the end of the path', () => {\n      expect(decoder.run({a: ['a', {b: 12}]})).toMatchObject({\n        ok: false,\n        error: {at: 'input.a[1].b', message: 'expected a string, got a number'}\n      });\n    });\n  });\n\n  describe('decode an optional field', () => {\n    const decoder = valueAt(['a', 'b', 'c'], optional(string()));\n\n    it('fails when the path does not exist', () => {\n      const error = decoder.run({a: {x: 'cats'}});\n      expect(error).toMatchObject({\n        ok: false,\n        error: {at: 'input.a.b.c', message: 'path does not exist'}\n      });\n    });\n\n    it('succeeds when the final field is not found', () => {\n      expect(decoder.run({a: {b: {z: 1}}})).toEqual({ok: true, result: undefined});\n    });\n  });\n\n  describe('non-object json', () => {\n    it('only accepts json objects and arrays', () => {\n      const decoder = valueAt(['a'], string());\n\n      expect(decoder.run('abc')).toMatchObject({\n        ok: false,\n        error: {at: 'input.a', message: 'expected an object, got a string'}\n      });\n      expect(decoder.run(true)).toMatchObject({\n        ok: false,\n        error: {at: 'input.a', message: 'expected an object, got a boolean'}\n      });\n    });\n\n    it('fails when a feild in the path does not correspond to a json object', () => {\n      const decoder = valueAt(['a', 'b', 'c'], string());\n\n      const error = decoder.run({a: {b: 1}});\n      expect(error).toMatchObject({\n        ok: false,\n        error: {at: 'input.a.b.c', message: 'expected an object, got a number'}\n      });\n    });\n\n    it('fails when an index in the path does not correspond to a json array', () => {\n      const decoder = valueAt([0, 0, 1], string());\n\n      const error = decoder.run([[false]]);\n      expect(error).toMatchObject({\n        ok: false,\n        error: {at: 'input[0][0][1]', message: 'expected an array, got a boolean'}\n      });\n    });\n  });\n\n  it('decodes the input when given an empty path', () => {\n    const decoder = valueAt([], number());\n\n    expect(decoder.run(12)).toEqual({ok: true, result: 12});\n  });\n});\n\ndescribe('succeed', () => {\n  const decoder = succeed(12345);\n\n  it('always decodes the input as the same value', () => {\n    expect(decoder.run('pancakes')).toEqual({ok: true, result: 12345});\n    expect(decoder.run(5)).toEqual({ok: true, result: 12345});\n  });\n});\n\ndescribe('fail', () => {\n  const wisdom = 'People don’t think it be like it is, but it do.';\n  const decoder = fail(wisdom);\n\n  it('always fails and returns the same error message', () => {\n    expect(decoder.run('pancakes')).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: wisdom}\n    });\n    expect(decoder.run(5)).toMatchObject({ok: false, error: {at: 'input', message: wisdom}});\n  });\n});\n\ndescribe('lazy', () => {\n  describe('decoding a primitive data type', () => {\n    const decoder = lazy(() => string());\n\n    it('can decode type as normal', () => {\n      expect(decoder.run('hello')).toEqual({ok: true, result: 'hello'});\n    });\n\n    it('does not alter the error message', () => {\n      expect(decoder.run(5)).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: 'expected a string, got a number'}\n      });\n    });\n  });\n\n  describe('decoding a recursive data structure', () => {\n    interface Comment {\n      msg: string;\n      replies: Comment[];\n    }\n\n    const decoder: Decoder<Comment> = object({\n      msg: string(),\n      replies: lazy(() => array(decoder))\n    });\n\n    it('can decode the data structure', () => {\n      const tree = {msg: 'hey', replies: [{msg: 'hi', replies: []}]};\n\n      expect(decoder.run(tree)).toEqual({\n        ok: true,\n        result: {msg: 'hey', replies: [{msg: 'hi', replies: []}]}\n      });\n    });\n\n    it('fails when a nested value is invalid', () => {\n      const badTree = {msg: 'hey', replies: [{msg: 'hi', replies: ['hello']}]};\n\n      expect(decoder.run(badTree)).toMatchObject({\n        ok: false,\n        error: {at: 'input.replies[0].replies[0]', message: 'expected an object, got a string'}\n      });\n    });\n  });\n});\n\ndescribe('runPromise', () => {\n  const promise = (json: unknown): Promise<boolean> => boolean().runPromise(json);\n\n  it('resolves the promise when the decoder succeeds', () => {\n    return expect(promise(true)).resolves.toBe(true);\n  });\n\n  it('rejects the promise when the decoder fails', () => {\n    return expect(promise(42)).rejects.toEqual({\n      kind: 'DecoderError',\n      input: 42,\n      at: 'input',\n      message: 'expected a boolean, got a number'\n    });\n  });\n\n  it('returns a DecoderError when the decoder fails', () => {\n    return expect(promise(42).catch(e => isDecoderError(e))).resolves.toBeTruthy();\n  });\n});\n\ndescribe('runWithException', () => {\n  const decoder = boolean();\n\n  it('can run a decoder and return the successful value', () => {\n    expect(decoder.runWithException(false)).toBe(false);\n  });\n\n  it('throws an exception when the decoder fails', () => {\n    let thrownError: any;\n\n    try {\n      decoder.runWithException(42);\n    } catch (e) {\n      thrownError = e;\n    }\n\n    expect(thrownError).toEqual({\n      kind: 'DecoderError',\n      input: 42,\n      at: 'input',\n      message: 'expected a boolean, got a number'\n    });\n  });\n});\n\ndescribe('map', () => {\n  it('can apply the identity function to the decoder', () => {\n    const decoder = string().map(x => x);\n\n    expect(decoder.run('hey there')).toEqual({ok: true, result: 'hey there'});\n  });\n\n  it('can apply an endomorphic function to the decoder', () => {\n    const decoder = number().map(x => x * 5);\n\n    expect(decoder.run(10)).toEqual({ok: true, result: 50});\n  });\n\n  it('can apply a function that transforms the type', () => {\n    const decoder = string().map(x => x.length);\n\n    expect(decoder.run('hey')).toEqual({ok: true, result: 3});\n  });\n});\n\ndescribe('andThen', () => {\n  describe('creates decoders based on previous results', () => {\n    const versionDecoder = valueAt(['version'], number());\n    const infoDecoder3 = object({a: boolean()});\n\n    const decoder = versionDecoder.andThen(version => {\n      switch (version) {\n        case 3:\n          return infoDecoder3;\n        default:\n          return fail(`Unable to decode info, version ${version} is not supported.`);\n      }\n    });\n\n    it('can decode using both the first and second decoder', () => {\n      expect(decoder.run({version: 5, x: 'bootsncats'})).toMatchObject({\n        ok: false,\n        error: {at: 'input', message: 'Unable to decode info, version 5 is not supported.'}\n      });\n\n      expect(decoder.run({version: 3, a: true})).toEqual({ok: true, result: {a: true}});\n    });\n\n    it('fails when the first decoder fails', () => {\n      expect(decoder.run({version: null, a: true})).toMatchObject({\n        ok: false,\n        error: {at: 'input.version', message: 'expected a number, got null'}\n      });\n    });\n\n    it('fails when the second decoder fails', () => {\n      const json = {version: 3, a: 1};\n      expect(decoder.run(json)).toMatchObject({\n        ok: false,\n        error: {at: 'input.a', message: 'expected a boolean, got a number'}\n      });\n    });\n  });\n\n  it('creates decoders for custom types', () => {\n    type NonEmptyArray<T> = T[] & {__nonEmptyArrayBrand__: void};\n    const createNonEmptyArray = <T>(arr: T[]): NonEmptyArray<T> => arr as NonEmptyArray<T>;\n\n    const nonEmptyArrayDecoder = <T>(values: Decoder<T>): Decoder<NonEmptyArray<T>> =>\n      array(values).andThen(\n        arr =>\n          arr.length > 0\n            ? succeed(createNonEmptyArray(arr))\n            : fail(`expected a non-empty array, got an empty array`)\n      );\n\n    expect(nonEmptyArrayDecoder(number()).run([1, 2, 3])).toEqual({\n      ok: true,\n      result: [1, 2, 3]\n    });\n\n    expect(nonEmptyArrayDecoder(number()).run([])).toMatchObject({\n      ok: false,\n      error: {message: 'expected a non-empty array, got an empty array'}\n    });\n  });\n});\n\ndescribe('where', () => {\n  const chars = (length: number): Decoder<string> =>\n    string().where((s: string) => s.length === length, `expected a string of length ${length}`);\n\n  const range = (min: number, max: number): Decoder<number> =>\n    number().where(\n      (n: number) => n >= min && n <= max,\n      `expected a number between ${min} and ${max}`\n    );\n\n  it('can test for strings of a given length', () => {\n    expect(chars(7).run('7777777')).toEqual({ok: true, result: '7777777'});\n\n    expect(chars(7).run('666666')).toMatchObject({\n      ok: false,\n      error: {message: 'expected a string of length 7'}\n    });\n  });\n\n  it('can test for numbers in a given range', () => {\n    expect(range(1, 9).run(7)).toEqual({ok: true, result: 7});\n\n    expect(range(1, 9).run(12)).toMatchObject({\n      ok: false,\n      error: {message: 'expected a number between 1 and 9'}\n    });\n  });\n\n  it('reports when the base decoder fails', () => {\n    expect(chars(7).run(false)).toMatchObject({\n      ok: false,\n      error: {message: 'expected a string, got a boolean'}\n    });\n\n    expect(range(0, 1).run(null)).toMatchObject({\n      ok: false,\n      error: {message: 'expected a number, got null'}\n    });\n  });\n});\n\ndescribe('Result', () => {\n  describe('can run a decoder with default value', () => {\n    const decoder = number();\n\n    it('succeeds with the value', () => {\n      expect(Result.withDefault(0, decoder.run(12))).toEqual(12);\n    });\n\n    it('succeeds with the default value instead of failing', () => {\n      expect(Result.withDefault(0, decoder.run('999'))).toEqual(0);\n    });\n  });\n\n  it('can return successes from an array of decoded values', () => {\n    const json: unknown = [1, true, 2, 3, 'five', 4, []];\n    const jsonArray: unknown[] = Result.withDefault([], array().run(json));\n    const numbers: number[] = Result.successes(jsonArray.map(number().run));\n\n    expect(numbers).toEqual([1, 2, 3, 4]);\n  });\n});\n"
  },
  {
    "path": "test/phone-example.test.ts",
    "content": "import {\n  Decoder,\n  string,\n  number,\n  constant,\n  object,\n  array,\n  optional,\n  oneOf,\n  union\n} from '../src/index';\n\ndescribe('decode phone number objects', () => {\n  enum PhoneUse {\n    Mobile = 'Mobile',\n    Home = 'Home',\n    Work = 'Work'\n  }\n\n  interface PhoneNumber {\n    id: number;\n    use?: PhoneUse;\n  }\n\n  interface InternationalPhone extends PhoneNumber {\n    international: true;\n    rawNumber: string;\n  }\n\n  interface DomesticPhone extends PhoneNumber {\n    international: false;\n    areaCode: string;\n    prefix: string;\n    lineNumber: string;\n  }\n\n  type Phone = DomesticPhone | InternationalPhone;\n\n  const phoneUseDecoder: Decoder<PhoneUse> = oneOf(\n    constant(PhoneUse.Mobile),\n    constant(PhoneUse.Home),\n    constant(PhoneUse.Work)\n  );\n\n  const internationalPhoneDecoder: Decoder<InternationalPhone> = object({\n    id: number(),\n    use: optional(phoneUseDecoder),\n    international: constant(true),\n    rawNumber: string()\n  });\n\n  const domesticPhoneDecoder: Decoder<DomesticPhone> = object({\n    id: number(),\n    use: optional(phoneUseDecoder),\n    international: constant(false),\n    areaCode: string(),\n    prefix: string(),\n    lineNumber: string()\n  });\n\n  const phoneDecoder: Decoder<Phone> = union(domesticPhoneDecoder, internationalPhoneDecoder);\n\n  const phonesDecoder: Decoder<Phone[]> = array(phoneDecoder);\n\n  it('can decode both international and domestic phones', () => {\n    const json = [\n      {\n        id: 1,\n        use: 'Work',\n        international: false,\n        areaCode: '123',\n        prefix: '456',\n        lineNumber: '7890'\n      },\n      {\n        id: 2,\n        use: 'Work',\n        international: true,\n        rawNumber: '111234567890'\n      },\n      {\n        id: 3,\n        international: false,\n        areaCode: '000',\n        prefix: '000',\n        lineNumber: '5555'\n      }\n    ];\n\n    expect(phonesDecoder.run(json)).toEqual({ok: true, result: json});\n  });\n\n  it('fails when an object is neither an international or domestic phone', () => {\n    const json = [\n      {\n        id: 1,\n        use: 'Work',\n        international: false,\n        areaCode: '123',\n        prefix: '456',\n        lineNumber: '7890'\n      },\n      {\n        id: 5\n      }\n    ];\n\n    const error = phonesDecoder.run(json);\n    expect(error).toMatchObject({\n      ok: false,\n      error: {\n        at: 'input[1]',\n        message: [\n          'expected a value matching one of the decoders, got the errors ',\n          `[\"at error: the key 'international' is required but was not present\", `,\n          `\"at error: the key 'international' is required but was not present\"]`\n        ].join('')\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/tagged-json-example.test.ts",
    "content": "import {\n  Decoder,\n  string,\n  number,\n  boolean,\n  constant,\n  array,\n  dict,\n  union,\n  lazy\n} from '../src/index';\n\ndescribe('create tagged json objects', () => {\n  type TaggedJson =\n    | {tag: 'null'; value: null}\n    | {tag: 'string'; value: string}\n    | {tag: 'number'; value: number}\n    | {tag: 'boolean'; value: boolean}\n    | {tag: 'array'; value: Array<TaggedJson>}\n    | {tag: 'object'; value: {[name: string]: TaggedJson}};\n\n  const json: any = [{x: 1, y: 5}, {a: true, b: 'false'}, 1, true];\n\n  const taggedJsonDecoder: Decoder<TaggedJson> = union(\n    constant(null).map<TaggedJson>(value => ({tag: 'null', value: value})),\n    string().map<TaggedJson>(value => ({tag: 'string', value: value})),\n    number().map<TaggedJson>(value => ({tag: 'number', value: value})),\n    boolean().map<TaggedJson>(value => ({tag: 'boolean', value: value})),\n    lazy(() => array(taggedJsonDecoder).map<TaggedJson>(value => ({tag: 'array', value: value}))),\n    lazy(() => dict(taggedJsonDecoder).map<TaggedJson>(value => ({tag: 'object', value: value})))\n  );\n\n  it('maps json to tagged json', () => {\n    expect(taggedJsonDecoder.run(json)).toEqual({\n      ok: true,\n      result: {\n        tag: 'array',\n        value: [\n          {\n            tag: 'object',\n            value: {\n              x: {tag: 'number', value: 1},\n              y: {tag: 'number', value: 5}\n            }\n          },\n          {\n            tag: 'object',\n            value: {\n              a: {\n                tag: 'boolean',\n                value: true\n              },\n              b: {\n                tag: 'string',\n                value: 'false'\n              }\n            }\n          },\n          {\n            tag: 'number',\n            value: 1\n          },\n          {\n            tag: 'boolean',\n            value: true\n          }\n        ]\n      }\n    });\n  });\n});\n"
  },
  {
    "path": "test/user-example.test.ts",
    "content": "import {Decoder, string, number, boolean, object} from '../src/index';\n\ndescribe('decode json as User interface', () => {\n  interface User {\n    firstname: string;\n    lastname: string;\n    age: number;\n    active: boolean;\n  }\n\n  const userJson: any = {\n    firstname: 'John',\n    lastname: 'Doe',\n    age: 99,\n    active: false\n  };\n\n  const invalidUserJson: any = {\n    firstname: 'John',\n    lastName: 'Doe', // invalid camelCase\n    age: 99,\n    active: false\n  };\n\n  const userDecoder: Decoder<User> = object({\n    firstname: string(),\n    lastname: string(),\n    age: number(),\n    active: boolean()\n  });\n\n  it('successfuly passes through the valid user object', () => {\n    expect(userDecoder.run(userJson)).toEqual({\n      ok: true,\n      result: userJson\n    });\n  });\n\n  it('fails when a required key is missing', () => {\n    const error = userDecoder.run(invalidUserJson);\n    expect(error).toMatchObject({\n      ok: false,\n      error: {at: 'input', message: \"the key 'lastname' is required but was not present\"}\n    });\n  });\n});\n"
  },
  {
    "path": "tsconfig-test.json",
    "content": "{\n  \"compilerOptions\": {\n    \"moduleResolution\": \"node\",\n    \"target\": \"es5\",\n    \"module\": \"es2015\",\n    \"lib\": [\"es2015\", \"es2016\", \"es2017\", \"dom\"],\n    \"strict\": true,\n    \"sourceMap\": true,\n    \"declaration\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true,\n    \"declarationDir\": \"dist/types\",\n    \"outDir\": \"dist/es\",\n    \"typeRoots\": [\"node_modules/@types\"]\n  },\n  \"include\": [\"src\", \"test\"]\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"moduleResolution\": \"node\",\n    \"target\": \"es5\",\n    \"module\": \"es2015\",\n    \"lib\": [\"es2015\", \"es2016\", \"es2017\", \"dom\"],\n    \"strict\": true,\n    \"sourceMap\": true,\n    \"declaration\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"experimentalDecorators\": true,\n    \"emitDecoratorMetadata\": true,\n    \"declarationDir\": \"dist/types\",\n    \"outDir\": \"dist/es\",\n    \"typeRoots\": [\"node_modules/@types\"]\n  },\n  \"include\": [\"src\"]\n}\n"
  },
  {
    "path": "tslint.json",
    "content": "{\n  \"extends\": [\n    \"tslint-config-standard\",\n    \"tslint-config-prettier\"\n  ],\n  \"rules\": {\n    \"strict-type-predicates\": false\n  }\n}\n"
  }
]