[
  {
    "path": ".babelrc",
    "content": "{\n  \"presets\": [\"@babel/preset-env\", \"@babel/preset-typescript\"]\n}\n"
  },
  {
    "path": ".changeset/config.json",
    "content": "{\n  \"$schema\": \"https://unpkg.com/@changesets/config@3.0.0/schema.json\",\n  \"changelog\": [\n    \"@changesets/changelog-github\",\n    {\n      \"repo\": \"supermacro/neverthrow\"\n    }\n  ],\n  \"commit\": false,\n  \"fixed\": [],\n  \"linked\": [],\n  \"access\": \"public\",\n  \"baseBranch\": \"master\",\n  \"updateInternalDependencies\": \"patch\",\n  \"ignore\": []\n}\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  parser: '@typescript-eslint/parser',\n  env: {\n    node: true,\n  },\n  ignorePatterns: ['dist/', 'tests/'],\n  plugins: [\n    '@typescript-eslint',\n  ],\n  extends: [\n    'eslint:recommended',\n    'plugin:@typescript-eslint/eslint-recommended',\n    'plugin:@typescript-eslint/recommended',\n    'prettier/@typescript-eslint',\n    'plugin:prettier/recommended'\n  ],\n  rules: {\n    semi: 'off',\n    '@typescript-eslint/no-explicit-any': 'error',\n    '@typescript-eslint/semi': 'off',\n    '@typescript-eslint/explicit-function-return-type': 'off',\n    '@typescript-eslint/no-unused-vars': 'off',\n    '@typescript-eslint/interface-name-prefix': 'off',\n    '@typescript-eslint/member-delimiter-style': ['error', {\n      multiline: {\n        delimiter: 'none',\n      },\n      singleline: {\n        delimiter: 'semi',\n        requireLast: false\n      }\n    }]\n  },\n};\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\non:\n  pull_request:\n  push:\n    branches:\n      - master\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}\n  cancel-in-progress: true\n\nenv:\n  RUNNER_NODE_VERSION: 22\njobs:\n  install_deps:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - name: Use Node.js ${{ env.RUNNER_NODE_VERSION }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ env.RUNNER_NODE_VERSION }}\n      - name: cache dependencies\n        uses: actions/cache@v4\n        id: cache-dependencies\n        with:\n          path: \"node_modules\"\n          key: depends-node${{ env.RUNNER_NODE_VERSION }}-${{ hashFiles('package-lock.json') }}\n      - name: install dependencies\n        if: steps.cache-dependencies.outputs.cache-hit != 'true'\n        run: npm i\n  \n  typecheck:\n    runs-on: ubuntu-latest\n    needs: install_deps\n    steps:\n      - uses: actions/checkout@v4\n      - name: Use Node.js ${{ env.RUNNER_NODE_VERSION }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ env.RUNNER_NODE_VERSION }}\n      - name: restore dependencies cache\n        uses: actions/cache/restore@v4\n        with:\n          path: \"node_modules\"\n          key: depends-node${{ env.RUNNER_NODE_VERSION }}-${{ hashFiles('package-lock.json') }}\n      - name: typecheck\n        run: npm run typecheck\n  \n  lint:\n    runs-on: ubuntu-latest\n    needs: install_deps\n    steps:\n      - uses: actions/checkout@v4\n      - name: Use Node.js ${{ env.RUNNER_NODE_VERSION }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ env.RUNNER_NODE_VERSION }}\n      - name: restore dependencies cache\n        uses: actions/cache/restore@v4\n        with:\n          path: \"node_modules\"\n          key: depends-node${{ env.RUNNER_NODE_VERSION }}-${{ hashFiles('package-lock.json') }}\n      - name: lint\n        run: npm run lint\n\n  build:\n    runs-on: ubuntu-latest\n    needs: install_deps\n    steps:\n      - uses: actions/checkout@v4\n      - name: Use Node.js ${{ env.RUNNER_NODE_VERSION }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ env.RUNNER_NODE_VERSION }}\n      - name: restore dependencies cache\n        uses: actions/cache/restore@v4\n        with:\n          path: \"node_modules\"\n          key: depends-node${{ env.RUNNER_NODE_VERSION }}-${{ hashFiles('package-lock.json') }}\n      - name: build\n        run: npm run build\n      \n  test:\n    runs-on: ubuntu-latest\n    needs: install_deps\n    strategy:\n      matrix:\n        node-version: [18, 20, 22]\n    steps:\n      - uses: actions/checkout@v4\n      - name: Use Node.js ${{ matrix.node-version }}\n        uses: actions/setup-node@v4\n        with:\n          node-version: ${{ matrix.node-version }}\n      - name: restore dependencies cache\n        uses: actions/cache/restore@v4\n        with:\n          path: \"node_modules\"\n          key: depends-node${{ env.RUNNER_NODE_VERSION }}-${{ hashFiles('package-lock.json') }}\n      - name: test\n        run: npm run test\n  test_result:\n    runs-on: ubuntu-latest\n    needs: test\n    if: ${{ always() }}\n    steps:\n      - run: exit 1\n        if: ${{ needs.test.result != 'success' }}\n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\n\non:\n  push:\n    branches:\n      - master\n\nconcurrency: ${{ github.workflow }}-${{ github.ref }}\n\njobs:\n  create_pr:\n    name: Release\n    runs-on: ubuntu-latest\n    outputs:\n      hasChangesets: ${{ steps.changesets.outputs.hasChangesets }}\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n          cache: 'npm'\n\n      - run: npm i\n\n      - name: Create Release Pull Request\n        id: changesets\n        uses: changesets/action@v1\n        with:\n          version: npm run version\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n\n  release:\n    needs: create_pr\n    if: needs.create_pr.outputs.hasChangesets == 'false'\n    runs-on: ubuntu-latest\n    environment: deploy\n    steps:\n      - uses: actions/checkout@v4\n\n      - uses: actions/setup-node@v4\n        with:\n          node-version: 22\n          cache: 'npm'\n\n      - run: npm i\n\n      - name: release\n        id: changesets\n        uses: changesets/action@v1\n        with:\n          publish: npm run release\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}\n  "
  },
  {
    "path": ".gitignore",
    "content": "dist/\ntmp/\nnode_modules/\npublish.sh"
  },
  {
    "path": ".prettierrc.js",
    "content": "module.exports = {\n  semi: false,\n  trailingComma: \"all\",\n  singleQuote: true,\n  printWidth: 100,\n  tabWidth: 2\n};\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# neverthrow\n\n## 8.2.0\n\n### Minor Changes\n\n- [#615](https://github.com/supermacro/neverthrow/pull/615) [`85ed7fd`](https://github.com/supermacro/neverthrow/commit/85ed7fd3a1247e4c0e83bba13f5e874282243d75) Thanks [@konker](https://github.com/konker)! - Add orTee, which is the equivalent of andTee but for the error track.\n\n- [#584](https://github.com/supermacro/neverthrow/pull/584) [`acea44a`](https://github.com/supermacro/neverthrow/commit/acea44adb98dda2ca32fe4e882879461cc7cedc2) Thanks [@macksal](https://github.com/macksal)! - Allow ok/err/okAsync/errAsync to accept zero arguments when returning void\n\n## 8.1.1\n\n### Patch Changes\n\n- [#600](https://github.com/supermacro/neverthrow/pull/600) [`3aee20a`](https://github.com/supermacro/neverthrow/commit/3aee20a1c429062d26f440fde32a3f26ef05533a) Thanks [@m-shaka](https://github.com/m-shaka)! - docs: updated README.md about `safeTry` and added @deprecated tag to safeUnwrap\n\n## 8.1.0\n\n### Minor Changes\n\n- [#589](https://github.com/supermacro/neverthrow/pull/589) [`609b398`](https://github.com/supermacro/neverthrow/commit/609b398aa1fd258a1fede974707d54eb4c230f3c) Thanks [@dmmulroy](https://github.com/dmmulroy)! - safeTry should not require .safeUnwrap()\n\n## 8.0.0\n\n### Major Changes\n\n- [#484](https://github.com/supermacro/neverthrow/pull/484) [`09faf35`](https://github.com/supermacro/neverthrow/commit/09faf35a5ce701ed55b13b82074da9e50050526d) Thanks [@braxtonhall](https://github.com/braxtonhall)! - Allow orElse method to change ok types.\n  This makes the orElse types match the implementation.\n\n  This is a breaking change for the orElse type argument list,\n  as the ok type must now be provided before the err type.\n\n  ```diff\n  - result.orElse<ErrType>(foo)\n  + result.orElse<OkType, ErrType>(foo)\n  ```\n\n  This only applies if type arguments were\n  explicitly provided at an orElse callsite.\n  If the type arguments were inferred,\n  no updates are needed during the upgrade.\n\n## 7.2.0\n\n### Minor Changes\n\n- [#562](https://github.com/supermacro/neverthrow/pull/562) [`547352f`](https://github.com/supermacro/neverthrow/commit/547352f326206b2c5b403bde4ddc88825172f25c) Thanks [@sharno](https://github.com/sharno)! - change the return type of `safeTry` to be `ResultAsync<T, E>` instead of `Promise<Result<T, E>>` for better composability\n\n## 7.1.0\n\n### Minor Changes\n\n- [#467](https://github.com/supermacro/neverthrow/pull/467) [`4b9d2fd`](https://github.com/supermacro/neverthrow/commit/4b9d2fdaf03223945068509f948b57194732aa03) Thanks [@untidy-hair\n  ](https://github.com/untidy-hair)! - feat: add `andTee` and `andThrough` to handle side-effect\n\n### Patch Changes\n\n- [#483](https://github.com/supermacro/neverthrow/pull/483) [`96f7f66`](https://github.com/supermacro/neverthrow/commit/96f7f669ac83be705a389d47ed804e9d44a13932) Thanks [@braxtonhall](https://github.com/braxtonhall)! - Fix `combineWithAllErrors` types\n\n- [#563](https://github.com/supermacro/neverthrow/pull/563) [`eadf50c`](https://github.com/supermacro/neverthrow/commit/eadf50c695db896b8841c0ee301ae5eeba994b90) Thanks [@mattpocock](https://github.com/mattpocock)! - Made err() infer strings narrowly for easier error tagging.\n\n## 7.0.1\n\n### Patch Changes\n\n- [#527](https://github.com/supermacro/neverthrow/pull/527) [`2e1f198`](https://github.com/supermacro/neverthrow/commit/2e1f19899800ce5e1164412c6a693cf2f1c40b20) Thanks [@3846masa](https://github.com/3846masa)! - fix: change type definitions to make inferring types of safeTry more strict\n\n- [#497](https://github.com/supermacro/neverthrow/pull/497) [`e06203e`](https://github.com/supermacro/neverthrow/commit/e06203e90b2b64edaa42707cbca8383c9f4765e8) Thanks [@braxtonhall](https://github.com/braxtonhall)! - enhance type inferrence of `match`\n\n## 7.0.0\n\n### Major Changes\n\n- [#553](https://github.com/supermacro/neverthrow/pull/553) [`5a3af0a`](https://github.com/supermacro/neverthrow/commit/5a3af0a55d0c440dfd50bfbbe021c6e4b973184b) Thanks [@m-shaka](https://github.com/m-shaka)! - Declare the minimum supported Node.js version\n\n  `Neverthrow` does not depend on any Node.js version-specific features, so it should work with any version of Node.js that supports ES6 and other runtimes like Browser, Deno, etc.\n\n  However, for the sake of maintaining a consistent development environment, we should declare the minimum supported version of Node.js in the `engines` field of the `package.json` file.\n"
  },
  {
    "path": "CODEOWNERS",
    "content": "* @m-shaka @supermacro\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2019 Giorgio Delgado\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, 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\n"
  },
  {
    "path": "README.md",
    "content": "# NeverThrow 🙅\n\n[![GitHub Workflow Status](https://github.com/supermacro/neverthrow/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/supermacro/neverthrow/actions)\n\n## Description\n\nEncode failure into your program.\n\n![Demo](assets/demo.png)\n\nThis package contains a `Result` type that represents either success (`Ok`) or failure (`Err`).\n\nFor asynchronous tasks, `neverthrow` offers a `ResultAsync` class which wraps a `Promise<Result<T, E>>` and gives you the same level of expressivity and control as a regular `Result<T, E>`.\n\n`ResultAsync` is `thenable` meaning it **behaves exactly like a native `Promise<Result>`** ... except you have access to the same methods that `Result` provides without having to `await` or `.then` the promise! Check out [the wiki](https://github.com/supermacro/neverthrow/wiki/Basic-Usage-Examples#asynchronous-api) for examples and best practices.\n\n> Need to see real-life examples of how to leverage this package for error handling? See this repo: https://github.com/parlez-vous/server\n\n<div id=\"toc\"></div>\n\n## Table Of Contents\n\n* [Installation](#installation)\n* [Recommended: Use `eslint-plugin-neverthrow`](#recommended-use-eslint-plugin-neverthrow)\n* [Top-Level API](#top-level-api)\n* [API Documentation](#api-documentation)\n  + [Synchronous API (`Result`)](#synchronous-api-result)\n    - [`ok`](#ok)\n    - [`err`](#err)\n    - [`Result.isOk` (method)](#resultisok-method)\n    - [`Result.isErr` (method)](#resultiserr-method)\n    - [`Result.map` (method)](#resultmap-method)\n    - [`Result.mapErr` (method)](#resultmaperr-method)\n    - [`Result.unwrapOr` (method)](#resultunwrapor-method)\n    - [`Result.andThen` (method)](#resultandthen-method)\n    - [`Result.asyncAndThen` (method)](#resultasyncandthen-method)\n    - [`Result.orElse` (method)](#resultorelse-method)\n    - [`Result.match` (method)](#resultmatch-method)\n    - [`Result.asyncMap` (method)](#resultasyncmap-method)\n    - [`Result.andTee` (method)](#resultandtee-method)\n    - [`Result.orTee` (method)](#resultortee-method)\n    - [`Result.andThrough` (method)](#resultandthrough-method)\n    - [`Result.asyncAndThrough` (method)](#resultasyncandthrough-method)\n    - [`Result.fromThrowable` (static class method)](#resultfromthrowable-static-class-method)\n    - [`Result.combine` (static class method)](#resultcombine-static-class-method)\n    - [`Result.combineWithAllErrors` (static class method)](#resultcombinewithallerrors-static-class-method)\n    - [`Result.safeUnwrap()`](#resultsafeunwrap)\n  + [Asynchronous API (`ResultAsync`)](#asynchronous-api-resultasync)\n    - [`okAsync`](#okasync)\n    - [`errAsync`](#errasync)\n    - [`ResultAsync.fromThrowable` (static class method)](#resultasyncfromthrowable-static-class-method)\n    - [`ResultAsync.fromPromise` (static class method)](#resultasyncfrompromise-static-class-method)\n    - [`ResultAsync.fromSafePromise` (static class method)](#resultasyncfromsafepromise-static-class-method)\n    - [`ResultAsync.map` (method)](#resultasyncmap-method)\n    - [`ResultAsync.mapErr` (method)](#resultasyncmaperr-method)\n    - [`ResultAsync.unwrapOr` (method)](#resultasyncunwrapor-method)\n    - [`ResultAsync.andThen` (method)](#resultasyncandthen-method)\n    - [`ResultAsync.orElse` (method)](#resultasyncorelse-method)\n    - [`ResultAsync.match` (method)](#resultasyncmatch-method)\n    - [`ResultAsync.andTee` (method)](#resultasyncandtee-method)\n    - [`ResultAsync.orTee` (method)](#resultasyncortee-method)\n    - [`ResultAsync.andThrough` (method)](#resultasyncandthrough-method)\n    - [`ResultAsync.combine` (static class method)](#resultasynccombine-static-class-method)\n    - [`ResultAsync.combineWithAllErrors` (static class method)](#resultasynccombinewithallerrors-static-class-method)\n    - [`ResultAsync.safeUnwrap()`](#resultasyncsafeunwrap)\n  + [Utilities](#utilities)\n    - [`fromThrowable`](#fromthrowable)\n    - [`fromAsyncThrowable`](#fromasyncthrowable)\n    - [`fromPromise`](#frompromise)\n    - [`fromSafePromise`](#fromsafepromise)\n    - [`safeTry`](#safetry)\n  + [Testing](#testing)\n* [A note on the Package Name](#a-note-on-the-package-name)\n\n## Installation\n\n```sh\n> npm install neverthrow\n```\n\n## Recommended: Use `eslint-plugin-neverthrow`\n\nAs part of `neverthrow`s [bounty program](https://github.com/supermacro/neverthrow/issues/314), user [mdbetancourt](https://github.com/mdbetancourt) created [`eslint-plugin-neverthrow`](https://github.com/mdbetancourt/eslint-plugin-neverthrow) to ensure that errors are not gone unhandled.\n\nInstall by running:\n\n```sh\n> npm install eslint-plugin-neverthrow\n```\n\nWith `eslint-plugin-neverthrow`, you are forced to consume the result in one of the following three ways:\n\n- Calling `.match`\n- Calling `.unwrapOr`\n- Calling `._unsafeUnwrap`\n\nThis ensures that you're explicitly handling the error of your `Result`.\n\nThis plugin is essentially a porting of Rust's [`must-use`](https://doc.rust-lang.org/std/result/#results-must-be-used) attribute. \n\n\n## Top-Level API\n\n`neverthrow` exposes the following:\n\n- `ok` convenience function to create an `Ok` variant of `Result`\n- `err` convenience function to create an `Err` variant of `Result`\n- `Ok` class and type\n- `Err` class and type\n- `Result` Type as well as namespace / object from which to call [`Result.fromThrowable`](#resultfromthrowable-static-class-method), [Result.combine](#resultcombine-static-class-method).\n- `ResultAsync` class\n- `okAsync` convenience function to create a `ResultAsync` containing an `Ok` type `Result`\n- `errAsync` convenience function to create a `ResultAsync` containing an `Err` type `Result`\n\n```typescript\nimport {\n  ok,\n  Ok,\n  err,\n  Err,\n  Result,\n  okAsync,\n  errAsync,\n  ResultAsync,\n  fromAsyncThrowable,\n  fromThrowable,\n  fromPromise,\n  fromSafePromise,\n  safeTry,\n} from 'neverthrow'\n```\n\n---\n\n**Check out the [wiki](https://github.com/supermacro/neverthrow/wiki) for help on how to make the most of `neverthrow`.**\n\nIf you find this package useful, please consider [sponsoring me](https://github.com/sponsors/supermacro/) or simply [buying me a coffee](https://ko-fi.com/gdelgado)!\n\n---\n\n## API Documentation\n\n### Synchronous API (`Result`)\n\n#### `ok`\n\nConstructs an `Ok` variant of `Result`\n\n**Signature:**\n\n```typescript\nok<T, E>(value: T): Ok<T, E> { ... }\n```\n\n**Example:**\n\n```typescript\nimport { ok } from 'neverthrow'\n\nconst myResult = ok({ myData: 'test' }) // instance of `Ok`\n\nmyResult.isOk() // true\nmyResult.isErr() // false\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `err`\n\nConstructs an `Err` variant of `Result`\n\n**Signature:**\n\n```typescript\nerr<T, E>(error: E): Err<T, E> { ... }\n```\n\n**Example:**\n\n```typescript\nimport { err } from 'neverthrow'\n\nconst myResult = err('Oh noooo') // instance of `Err`\n\nmyResult.isOk() // false\nmyResult.isErr() // true\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.isOk` (method)\n\nReturns `true` if the result is an `Ok` variant\n\n**Signature:**\n\n```typescript\nisOk(): boolean { ... }\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.isErr` (method)\n\nReturns `true` if the result is an `Err` variant\n\n**Signature**:\n\n```typescript\nisErr(): boolean { ... }\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.map` (method)\n\nMaps a `Result<T, E>` to `Result<U, E>` by applying a function to a contained `Ok` value, leaving an `Err` value untouched.\n\nThis function can be used to compose the results of two functions.\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  map<U>(callback: (value: T) => U): Result<U, E> { ... }\n}\n```\n\n**Example**:\n\n```typescript\nimport { getLines } from 'imaginary-parser'\n// ^ assume getLines has the following signature:\n// getLines(str: string): Result<Array<string>, Error>\n\n// since the formatting is deemed correct by `getLines`\n// then it means that `linesResult` is an Ok\n// containing an Array of strings for each line of code\nconst linesResult = getLines('1\\n2\\n3\\n4\\n')\n\n// this Result now has a Array<number> inside it\nconst newResult = linesResult.map(\n  (arr: Array<string>) => arr.map(parseInt)\n)\n\nnewResult.isOk() // true\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.mapErr` (method)\n\nMaps a `Result<T, E>` to `Result<T, F>` by applying a function to a contained `Err` value, leaving an `Ok` value untouched.\n\nThis function can be used to pass through a successful result while handling an error.\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  mapErr<F>(callback: (error: E) => F): Result<T, F> { ... }\n}\n```\n\n**Example**:\n\n```typescript\nimport { parseHeaders } from 'imaginary-http-parser'\n// imagine that parseHeaders has the following signature:\n// parseHeaders(raw: string): Result<SomeKeyValueMap, ParseError>\n\nconst rawHeaders = 'nonsensical gibberish and badly formatted stuff'\n\nconst parseResult = parseHeaders(rawHeaders)\n\nparseResult.mapErr(parseError => {\n  res.status(400).json({\n    error: parseError\n  })\n})\n\nparseResult.isErr() // true\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.unwrapOr` (method)\n\nUnwrap the `Ok` value, or return the default if there is an `Err`\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  unwrapOr<T>(value: T): T { ... }\n}\n```\n\n**Example**:\n\n```typescript\nconst myResult = err('Oh noooo')\n\nconst multiply = (value: number): number => value * 2\n\nconst unwrapped: number = myResult.map(multiply).unwrapOr(10)\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.andThen` (method)\n\nSame idea as `map` above. Except you must return a new `Result`.\n\nThe returned value will be a `Result`. As of `v4.1.0-beta`, you are able to return distinct error types (see signature below). Prior to `v4.1.0-beta`, the error type could not be distinct.\n\nThis is useful for when you need to do a subsequent computation using the inner `T` value, but that computation might fail.\n\nAdditionally, `andThen` is really useful as a tool to flatten a `Result<Result<A, E2>, E1>` into a `Result<A, E2>` (see example below).\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  // Note that the latest version lets you return distinct errors as well.\n  // If the error types (E and F) are the same (like `string | string`)\n  // then they will be merged into one type (`string`)\n  andThen<U, F>(\n    callback: (value: T) => Result<U, F>\n  ): Result<U, E | F> { ... }\n}\n```\n\n**Example 1: Chaining Results**\n\n```typescript\nimport { err, ok } from 'neverthrow'\n\nconst sq = (n: number): Result<number, number> => ok(n ** 2)\n\nok(2)\n  .andThen(sq)\n  .andThen(sq) // Ok(16)\n\nok(2)\n  .andThen(sq)\n  .andThen(err) // Err(4)\n\nok(2)\n  .andThen(err)\n  .andThen(sq) // Err(2)\n\nerr(3)\n  .andThen(sq)\n  .andThen(sq) // Err(3)\n```\n\n**Example 2: Flattening Nested Results**\n\n```typescript\n// It's common to have nested Results\nconst nested = ok(ok(1234))\n\n// notNested is a Ok(1234)\nconst notNested = nested.andThen((innerResult) => innerResult)\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.asyncAndThen` (method)\n\nSame idea as [`andThen` above](#resultandthen-method), except you must return a new `ResultAsync`.\n\nThe returned value will be a `ResultAsync`.\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  asyncAndThen<U, F>(\n    callback: (value: T) => ResultAsync<U, F>\n  ): ResultAsync<U, E | F> { ... }\n}\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.orElse` (method)\n\nTakes an `Err` value and maps it to a `Result<T, SomeNewType>`. This is useful for error recovery.\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  orElse<U, A>(\n    callback: (error: E) => Result<U, A>\n  ): Result<U | T, A> { ... }\n}\n```\n\n**Example:**\n\n```typescript\nenum DatabaseError {\n  PoolExhausted = 'PoolExhausted',\n  NotFound = 'NotFound',\n}\n\nconst dbQueryResult: Result<string, DatabaseError> = err(DatabaseError.NotFound)\n\nconst updatedQueryResult = dbQueryResult.orElse((dbError) =>\n  dbError === DatabaseError.NotFound\n    ? ok('User does not exist') // error recovery branch: ok() must be called with a value of type string\n    //\n    //\n    // err() can be called with a value of any new type that you want\n    // it could also be called with the same error value\n    //     \n    //     err(dbError)\n    : err(500) \n)\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.match` (method)\n\nGiven 2 functions (one for the `Ok` variant and one for the `Err` variant) execute the function that matches the `Result` variant.\n\nMatch callbacks do not necessitate to return a `Result`, however you can return a `Result` if you want to.\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  match<A, B = A>(\n    okCallback: (value: T) =>  A,\n    errorCallback: (error: E) =>  B\n  ): A | B => { ... }\n}\n```\n\n`match` is like chaining `map` and `mapErr`, with the distinction that with `match` both functions must have the same return type.\nThe differences between `match` and chaining `map` and `mapErr` are that:\n- with `match` both functions must have the same return type `A`\n- `match` unwraps the `Result<T, E>` into an `A` (the match functions' return type)\n  - This makes no difference if you are performing side effects only\n\n**Example:**\n\n```typescript\n// map/mapErr api\n// note that you DON'T have to append mapErr\n// after map which means that you are not required to do\n// error handling\ncomputationThatMightFail().map(console.log).mapErr(console.error)\n\n// match api\n// works exactly the same as above since both callbacks\n// only perform side effects,\n// except, now you HAVE to do error handling :)\ncomputationThatMightFail().match(console.log, console.error)\n\n// Returning values\nconst attempt = computationThatMightFail()\n  .map((str) => str.toUpperCase())\n  .mapErr((err) => `Error: ${err}`)\n// `attempt` is of type `Result<string, string>`\n\nconst answer = computationThatMightFail().match(\n  (str) => str.toUpperCase(),\n  (err) => `Error: ${err}`\n)\n// `answer` is of type `string`\n```\n\nIf you don't use the error parameter in your match callback then `match` is equivalent to chaining `map` with `unwrapOr`:\n```ts\nconst answer = computationThatMightFail().match(\n  (str) => str.toUpperCase(),\n  () => 'ComputationError'\n)\n// `answer` is of type `string`\n\nconst answer = computationThatMightFail()\n  .map((str) => str.toUpperCase())\n  .unwrapOr('ComputationError')\n```\n\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.asyncMap` (method)\n\nSimilar to `map` except for two things:\n\n- the mapping function must return a `Promise`\n- asyncMap returns a `ResultAsync`\n\nYou can then chain the result of `asyncMap` using the `ResultAsync` apis (like `map`, `mapErr`, `andThen`, etc.)\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  asyncMap<U>(\n    callback: (value: T) => Promise<U>\n  ): ResultAsync<U, E> { ... }\n}\n```\n\n**Example:**\n\n```typescript\nimport { parseHeaders } from 'imaginary-http-parser'\n// imagine that parseHeaders has the following signature:\n// parseHeaders(raw: string): Result<SomeKeyValueMap, ParseError>\n\nconst asyncRes = parseHeaders(rawHeader)\n  .map(headerKvMap => headerKvMap.Authorization)\n  .asyncMap(findUserInDatabase)\n```\n\nNote that in the above example if `parseHeaders` returns an `Err` then `.map` and `.asyncMap` will not be invoked, and `asyncRes` variable will resolve to an `Err` when turned into a `Result` using `await` or `.then()`.\n  \n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.andTee` (method)\n\nTakes a `Result<T, E>` and lets the original `Result<T, E>` pass through regardless the result of the passed-in function.\nThis is a handy way to handle side effects whose failure or success should not affect your main logics such as logging. \n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  andTee(\n    callback: (value: T) => unknown\n  ): Result<T, E> { ... }\n}\n```\n\n**Example:**\n\n```typescript\nimport { parseUserInput } from 'imaginary-parser'\nimport { logUser } from 'imaginary-logger'\nimport { insertUser } from 'imaginary-database'\n\n// ^ assume parseUserInput, logUser and insertUser have the following signatures:\n// parseUserInput(input: RequestData): Result<User, ParseError>\n// logUser(user: User): Result<void, LogError> \n// insertUser(user: User): ResultAsync<void, InsertError>\n// Note logUser returns void upon success but insertUser takes User type.\n\nconst resAsync = parseUserInput(userInput)\n               .andTee(logUser)\n               .asyncAndThen(insertUser)\n\n// Note no LogError shows up in the Result type\nresAsync.then((res: Result<void, ParseError | InsertError>) => {\n  if(res.isErr()){\n    console.log(\"Oops, at least one step failed\", res.error)\n  }\n  else{\n    console.log(\"User input has been parsed and inserted successfully.\")\n  }\n})\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.orTee` (method)\n\nLike `andTee` for the error track. Takes a `Result<T, E>` and lets the `Err` value pass through regardless the result of the passed-in function.\nThis is a handy way to handle side effects whose failure or success should not affect your main logics such as logging.\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  orTee(\n    callback: (value: E) => unknown\n  ): Result<T, E> { ... }\n}\n```\n\n**Example:**\n\n```typescript\nimport { parseUserInput } from 'imaginary-parser'\nimport { logParseError } from 'imaginary-logger'\nimport { insertUser } from 'imaginary-database'\n\n// ^ assume parseUserInput, logParseError and insertUser have the following signatures:\n// parseUserInput(input: RequestData): Result<User, ParseError>\n// logParseError(parseError: ParseError): Result<void, LogError> \n// insertUser(user: User): ResultAsync<void, InsertError>\n// Note logParseError returns void upon success but insertUser takes User type.\n\nconst resAsync = parseUserInput(userInput)\n               .orTee(logParseError)\n               .asyncAndThen(insertUser)\n\n// Note no LogError shows up in the Result type\nresAsync.then((res: Result<void, ParseError | InsertError>) => {\n  if(res.isErr()){\n    console.log(\"Oops, at least one step failed\", res.error)\n  }\n  else{\n    console.log(\"User input has been parsed and inserted successfully.\")\n  }\n})\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.andThrough` (method)\n\nSimilar to `andTee` except for:\n\n- when there is an error from the passed-in function, that error will be passed along.\n\n**Signature:**\n\n```typescript\nclass Result<T, E> {\n  andThrough<F>(\n    callback: (value: T) => Result<unknown, F>\n  ): Result<T, E | F> { ... }\n}\n```\n\n**Example:**\n\n```typescript\nimport { parseUserInput } from 'imaginary-parser'\nimport { validateUser } from 'imaginary-validator'\nimport { insertUser } from 'imaginary-database'\n\n// ^ assume parseUseInput, validateUser and insertUser have the following signatures:\n// parseUserInput(input: RequestData): Result<User, ParseError>\n// validateUser(user: User): Result<void, ValidateError>\n// insertUser(user: User): ResultAsync<void, InsertError>\n// Note validateUser returns void upon success but insertUser takes User type. \n\nconst resAsync = parseUserInput(userInput)\n               .andThrough(validateUser)\n               .asyncAndThen(insertUser)\n\nresAsync.then((res: Result<void, ParseError | ValidateError | InsertError>) => {\n  if(res.isErr()){\n    console.log(\"Oops, at least one step failed\", res.error)\n  }\n  else{\n    console.log(\"User input has been parsed, validated, inserted successfully.\")\n  }\n})\n```\n  \n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.asyncAndThrough` (method)\n\nSimilar to `andThrough` except you must return a ResultAsync. \n\nYou can then chain the result of `asyncAndThrough` using the `ResultAsync` apis (like `map`, `mapErr`, `andThen`, etc.)\n\n**Signature:**\n\n```typescript\nimport { parseUserInput } from 'imaginary-parser'\nimport { insertUser } from 'imaginary-database'\nimport { sendNotification } from 'imaginary-service'\n\n// ^ assume parseUserInput, insertUser and sendNotification have the following signatures:\n// parseUserInput(input: RequestData): Result<User, ParseError>\n// insertUser(user: User): ResultAsync<void, InsertError>\n// sendNotification(user: User): ResultAsync<void, NotificationError>\n// Note insertUser returns void upon success but sendNotification takes User type. \n\nconst resAsync = parseUserInput(userInput)\n               .asyncAndThrough(insertUser)\n               .andThen(sendNotification)\n\nresAsync.then((res: Result<void, ParseError | InsertError | NotificationError>) => {\n  if(res.isErr()){\n    console.log(\"Oops, at least one step failed\", res.error)\n  }\n  else{\n    console.log(\"User has been parsed, inserted and notified successfully.\")\n  }\n})\n```\n  \n[⬆️  Back to top](#toc)\n\n---\n#### `Result.fromThrowable` (static class method)\n\n> Although Result is not an actual JS class, the way that `fromThrowable` has been implemented requires that you call `fromThrowable` as though it were a static method on `Result`. See examples below.\n\nThe JavaScript community has agreed on the convention of throwing exceptions.\nAs such, when interfacing with third party libraries it's imperative that you\nwrap third-party code in try / catch blocks.\n\nThis function will create a new function that returns an `Err` when the original\nfunction throws.\n\nIt is not possible to know the types of the errors thrown in the original\nfunction, therefore it is recommended to use the second argument `errorFn` to\nmap what is thrown to a known type.\n\n**Example**:\n\n```typescript\nimport { Result } from 'neverthrow'\n\ntype ParseError = { message: string }\nconst toParseError = (): ParseError => ({ message: \"Parse Error\" })\n\nconst safeJsonParse = Result.fromThrowable(JSON.parse, toParseError)\n\n// the function can now be used safely, if the function throws, the result will be an Err\nconst res = safeJsonParse(\"{\");\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.combine` (static class method)\n\n> Although Result is not an actual JS class, the way that `combine` has been implemented requires that you call `combine` as though it were a static method on `Result`. See examples below.\n\nCombine lists of `Result`s.\n\nIf you're familiar with `Promise.all`, the combine function works conceptually the same.\n\n**`combine` works on both heterogeneous and homogeneous lists**. This means that you can have lists that contain different kinds of `Result`s and still be able to combine them. Note that you cannot combine lists that contain both `Result`s **and** `ResultAsync`s.\n\nThe combine function takes a list of results and returns a single result. If all the results in the list are `Ok`, then the return value will be a `Ok` containing a list of all the individual `Ok` values.\n\nIf just one of the results in the list is an `Err` then the combine function returns that Err value (it short circuits and returns the first Err that it finds).\n\nFormally speaking:\n\n```typescript\n// homogeneous lists\nfunction combine<T, E>(resultList: Result<T, E>[]): Result<T[], E>\n\n// heterogeneous lists\nfunction combine<T1, T2, E1, E2>(resultList: [ Result<T1, E1>, Result<T2, E2> ]): Result<[ T1, T2 ], E1 | E2>\nfunction combine<T1, T2, T3, E1, E2, E3> => Result<[ T1, T2, T3 ], E1 | E2 | E3>\nfunction combine<T1, T2, T3, T4, E1, E2, E3, E4> => Result<[ T1, T2, T3, T4 ], E1 | E2 | E3 | E4>\n// ... etc etc ad infinitum\n\n```\n\nExample:\n```typescript\nconst resultList: Result<number, never>[] =\n  [ok(1), ok(2)]\n\nconst combinedList: Result<number[], unknown> =\n  Result.combine(resultList)\n```\n\nExample with tuples:\n```typescript\n/** @example tuple(1, 2, 3) === [1, 2, 3] // with type [number, number, number] */\nconst tuple = <T extends any[]>(...args: T): T => args\n\nconst resultTuple: [Result<string, never>, Result<string, never>] =\n  tuple(ok('a'), ok('b'))\n\nconst combinedTuple: Result<[string, string], unknown> =\n  Result.combine(resultTuple)\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `Result.combineWithAllErrors` (static class method)\n\n> Although Result is not an actual JS class, the way that `combineWithAllErrors` has been implemented requires that you call `combineWithAllErrors` as though it were a static method on `Result`. See examples below.\n\nLike `combine` but without short-circuiting. Instead of just the first error value, you get a list of all error values of the input result list.\n\nIf only some results fail, the new combined error list will only contain the error value of the failed results, meaning that there is no guarantee of the length of the new error list.\n\nFunction signature:\n\n```typescript\n// homogeneous lists\nfunction combineWithAllErrors<T, E>(resultList: Result<T, E>[]): Result<T[], E[]>\n\n// heterogeneous lists\nfunction combineWithAllErrors<T1, T2, E1, E2>(resultList: [ Result<T1, E1>, Result<T2, E2> ]): Result<[ T1, T2 ], (E1 | E2)[]>\nfunction combineWithAllErrors<T1, T2, T3, E1, E2, E3> => Result<[ T1, T2, T3 ], (E1 | E2 | E3)[]>\nfunction combineWithAllErrors<T1, T2, T3, T4, E1, E2, E3, E4> => Result<[ T1, T2, T3, T4 ], (E1 | E2 | E3 | E4)[]>\n// ... etc etc ad infinitum\n```\n\nExample usage:\n\n```typescript\nconst resultList: Result<number, string>[] = [\n  ok(123),\n  err('boooom!'),\n  ok(456),\n  err('ahhhhh!'),\n]\n\nconst result = Result.combineWithAllErrors(resultList)\n\n// result is Err(['boooom!', 'ahhhhh!'])\n```\n\n[⬆️  Back to top](#toc)\n\n#### `Result.safeUnwrap()`\n\n**Deprecated**. You don't need to use this method anymore.\n\nAllows for unwrapping a `Result` or returning an `Err` implicitly, thereby reducing boilerplate.\n\n\n[⬆️  Back to top](#toc)\n\n---\n\n### Asynchronous API (`ResultAsync`)\n\n#### `okAsync`\n\nConstructs an `Ok` variant of `ResultAsync`\n\n**Signature:**\n\n```typescript\nokAsync<T, E>(value: T): ResultAsync<T, E>\n```\n\n**Example:**\n\n```typescript\nimport { okAsync } from 'neverthrow'\n\nconst myResultAsync = okAsync({ myData: 'test' }) // instance of `ResultAsync`\n\nconst myResult = await myResultAsync // instance of `Ok`\n\nmyResult.isOk() // true\nmyResult.isErr() // false\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `errAsync`\n\nConstructs an `Err` variant of `ResultAsync`\n\n**Signature:**\n\n```typescript\nerrAsync<T, E>(error: E): ResultAsync<T, E>\n```\n\n**Example:**\n\n```typescript\nimport { errAsync } from 'neverthrow'\n\nconst myResultAsync = errAsync('Oh nooo') // instance of `ResultAsync`\n\nconst myResult = await myResultAsync // instance of `Err`\n\nmyResult.isOk() // false\nmyResult.isErr() // true\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.fromThrowable` (static class method)\n\nSimilar to [Result.fromThrowable](#resultfromthrowable-static-class-method), but for functions that return a `Promise`.\n\n**Example**:\n\n```typescript\nimport { ResultAsync } from 'neverthrow'\nimport { insertIntoDb } from 'imaginary-database'\n// insertIntoDb(user: User): Promise<User>\n\nconst insertUser = ResultAsync.fromThrowable(insertIntoDb, () => new Error('Database error'))\n// `res` has a type of (user: User) => ResultAsync<User, Error>\n```\n\nNote that this can be safer than using [ResultAsync.fromPromise](#resultasyncfrompromise-static-class-method) with\nthe result of a function call, because not all functions that return a `Promise` are `async`, and thus they can throw\nerrors synchronously rather than returning a rejected `Promise`. For example:\n\n```typescript\n// NOT SAFE !!\nimport { ResultAsync } from 'neverthrow'\nimport { db } from 'imaginary-database'\n// db.insert<T>(table: string, value: T): Promise<T>\n\nconst insertUser = (user: User): Promise<User> => {\n  if (!user.id) {\n    // this throws synchronously!\n    throw new TypeError('missing user id')\n  }\n  return db.insert('users', user)\n}\n\n// this will throw, NOT return a `ResultAsync`\nconst res = ResultAsync.fromPromise(insertIntoDb(myUser), () => new Error('Database error'))\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.fromPromise` (static class method)\n\nTransforms a `PromiseLike<T>` (that may throw) into a `ResultAsync<T, E>`.\n\nThe second argument handles the rejection case of the promise and maps the error from `unknown` into some type `E`.\n\n\n**Signature:**\n\n```typescript\n// fromPromise is a static class method\n// also available as a standalone function\n// import { fromPromise } from 'neverthrow'\nResultAsync.fromPromise<T, E>(\n  promise: PromiseLike<T>,\n  errorHandler: (unknownError: unknown) => E)\n): ResultAsync<T, E> { ... }\n```\n\nIf you are working with `PromiseLike` objects that you **know for a fact** will not throw, then use `fromSafePromise` in order to avoid having to pass a redundant `errorHandler` argument.\n\n**Example**:\n\n```typescript\nimport { ResultAsync } from 'neverthrow'\nimport { insertIntoDb } from 'imaginary-database'\n// insertIntoDb(user: User): Promise<User>\n\nconst res = ResultAsync.fromPromise(insertIntoDb(myUser), () => new Error('Database error'))\n// `res` has a type of ResultAsync<User, Error>\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.fromSafePromise` (static class method)\n\nSame as `ResultAsync.fromPromise` except that it does not handle the rejection of the promise. **Ensure you know what you're doing, otherwise a thrown exception within this promise will cause ResultAsync to reject, instead of resolve to a Result.**\n\n**Signature:**\n\n```typescript\n// fromPromise is a static class method\n// also available as a standalone function\n// import { fromPromise } from 'neverthrow'\nResultAsync.fromSafePromise<T, E>(\n  promise: PromiseLike<T>\n): ResultAsync<T, E> { ... }\n```\n\n**Example**:\n\n```typescript\nimport { RouteError } from 'routes/error'\n\n// simulate slow routes in an http server that works in a Result / ResultAsync context\n// Adopted from https://github.com/parlez-vous/server/blob/2496bacf55a2acbebc30631b5562f34272794d76/src/routes/common/signup.ts\nexport const slowDown = <T>(ms: number) => (value: T) =>\n  ResultAsync.fromSafePromise<T, RouteError>(\n    new Promise((resolve) => {\n      setTimeout(() => {\n        resolve(value)\n      }, ms)\n    })\n  )\n\nexport const signupHandler = route<User>((req, sessionManager) =>\n  decode(userSignupDecoder, req.body, 'Invalid request body').map((parsed) => {\n    return createUser(parsed)\n      .andThen(slowDown(3000)) // slowdown by 3 seconds\n      .andThen(sessionManager.createSession)\n      .map(({ sessionToken, admin }) => AppData.init(admin, sessionToken))\n  })\n)\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.map` (method)\n\nMaps a `ResultAsync<T, E>` to `ResultAsync<U, E>` by applying a function to a contained `Ok` value, leaving an `Err` value untouched.\n\nThe applied function can be synchronous or asynchronous (returning a `Promise<U>`) with no impact to the return type.\n\nThis function can be used to compose the results of two functions.\n\n**Signature:**\n\n```typescript\nclass ResultAsync<T, E> {\n  map<U>(\n    callback: (value: T) => U | Promise<U>\n  ): ResultAsync<U, E> { ... }\n}\n```\n\n**Example**:\n\n```typescript\nimport { findUsersIn } from 'imaginary-database'\n// ^ assume findUsersIn has the following signature:\n// findUsersIn(country: string): ResultAsync<Array<User>, Error>\n\nconst usersInCanada = findUsersIn(\"Canada\")\n\n// Let's assume we only need their names\nconst namesInCanada = usersInCanada.map((users: Array<User>) => users.map(user => user.name))\n// namesInCanada is of type ResultAsync<Array<string>, Error>\n\n// We can extract the Result using .then() or await\nnamesInCanada.then((namesResult: Result<Array<string>, Error>) => {\n  if(namesResult.isErr()){\n    console.log(\"Couldn't get the users from the database\", namesResult.error)\n  }\n  else{\n    console.log(\"Users in Canada are named: \" + namesResult.value.join(','))\n  }\n})\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.mapErr` (method)\n\nMaps a `ResultAsync<T, E>` to `ResultAsync<T, F>` by applying a function to a contained `Err` value, leaving an `Ok` value untouched.\n\nThe applied function can be synchronous or asynchronous (returning a `Promise<F>`) with no impact to the return type.\n\nThis function can be used to pass through a successful result while handling an error.\n\n**Signature:**\n\n```typescript\nclass ResultAsync<T, E> {\n  mapErr<F>(\n    callback: (error: E) => F | Promise<F>\n  ): ResultAsync<T, F> { ... }\n}\n```\n\n**Example**:\n\n```typescript\nimport { findUsersIn } from 'imaginary-database'\n// ^ assume findUsersIn has the following signature:\n// findUsersIn(country: string): ResultAsync<Array<User>, Error>\n\n// Let's say we need to low-level errors from findUsersIn to be more readable\nconst usersInCanada = findUsersIn(\"Canada\").mapErr((error: Error) => {\n  // The only error we want to pass to the user is \"Unknown country\"\n  if(error.message === \"Unknown country\"){\n    return error.message\n  }\n  // All other errors will be labelled as a system error\n  return \"System error, please contact an administrator.\"\n})\n\n// usersInCanada is of type ResultAsync<Array<User>, string>\n\nusersInCanada.then((usersResult: Result<Array<User>, string>) => {\n  if(usersResult.isErr()){\n    res.status(400).json({\n      error: usersResult.error\n    })\n  }\n  else{\n    res.status(200).json({\n      users: usersResult.value\n    })\n  }\n})\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.unwrapOr` (method)\n\nUnwrap the `Ok` value, or return the default if there is an `Err`.  \nWorks just like `Result.unwrapOr` but returns a `Promise<T>` instead of `T`.\n\n**Signature:**\n\n```typescript\nclass ResultAsync<T, E> {\n  unwrapOr<T>(value: T): Promise<T> { ... }\n}\n```\n\n**Example**:\n\n```typescript\nconst unwrapped: number = await errAsync(0).unwrapOr(10)\n// unwrapped = 10\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.andThen` (method)\n\nSame idea as `map` above. Except the applied function must return a `Result` or `ResultAsync`.\n\n`ResultAsync.andThen` always returns a `ResultAsync` no matter the return type of the applied function.\n\nThis is useful for when you need to do a subsequent computation using the inner `T` value, but that computation might fail.\n\n`andThen` is really useful as a tool to flatten a `ResultAsync<ResultAsync<A, E2>, E1>` into a `ResultAsync<A, E2>` (see example below).\n\n**Signature:**\n\n```typescript\n// Note that the latest version (v4.1.0-beta) lets you return distinct errors as well.\n// If the error types (E and F) are the same (like `string | string`)\n// then they will be merged into one type (`string`)\n\nclass ResultAsync<T, E> {\n  andThen<U, F>(\n    callback: (value: T) => Result<U, F> | ResultAsync<U, F>\n  ): ResultAsync<U, E | F> { ... }\n}\n```\n\n**Example**\n\n```typescript\n\nimport { validateUser } from 'imaginary-validator'\nimport { insertUser } from 'imaginary-database'\nimport { sendNotification } from 'imaginary-service'\n\n// ^ assume validateUser, insertUser and sendNotification have the following signatures:\n// validateUser(user: User): Result<User, Error>\n// insertUser(user): ResultAsync<User, Error>\n// sendNotification(user): ResultAsync<void, Error>\n\nconst resAsync = validateUser(user)\n               .andThen(insertUser)\n               .andThen(sendNotification)\n\n// resAsync is a ResultAsync<void, Error>\n\nresAsync.then((res: Result<void, Error>) => {\n  if(res.isErr()){\n    console.log(\"Oops, at least one step failed\", res.error)\n  }\n  else{\n    console.log(\"User has been validated, inserted and notified successfully.\")\n  }\n})\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.orElse` (method)\n\nTakes an `Err` value and maps it to a `ResultAsync<T, SomeNewType>`. This is useful for error recovery.\n\n**Signature:**\n\n```typescript\nclass ResultAsync<T, E> {\n  orElse<U, A>(\n    callback: (error: E) => Result<U, A> | ResultAsync<U, A>\n  ): ResultAsync<U | T, A> { ... }\n}\n```\n\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.match` (method)\n\nGiven 2 functions (one for the `Ok` variant and one for the `Err` variant) execute the function that matches the `ResultAsync` variant.\n\nThe difference with `Result.match` is that it always returns a `Promise` because of the asynchronous nature of the `ResultAsync`.\n\n**Signature:**\n\n```typescript\nclass ResultAsync<T, E> {\n  match<A, B = A>(\n    okCallback: (value: T) =>  A,\n    errorCallback: (error: E) =>  B\n  ): Promise<A | B> => { ... }\n}\n```\n\n**Example:**\n\n```typescript\n\nimport { validateUser } from 'imaginary-validator'\nimport { insertUser } from 'imaginary-database'\n\n// ^ assume validateUser and insertUser have the following signatures:\n// validateUser(user: User): Result<User, Error>\n// insertUser(user): ResultAsync<User, Error>\n\n// Handle both cases at the end of the chain using match\nconst resultMessage = await validateUser(user)\n        .andThen(insertUser)\n        .match(\n            (user: User) => `User ${user.name} has been successfully created`,\n            (error: Error) =>  `User could not be created because ${error.message}`\n        )\n\n// resultMessage is a string\n```\n\n[⬆️  Back to top](#toc)\n\n---\n#### `ResultAsync.andTee` (method)\n\nTakes a `ResultAsync<T, E>` and lets the original `ResultAsync<T, E>` pass through regardless \nthe result of the passed-in function.\nThis is a handy way to handle side effects whose failure or success should not affect your main logics such as logging. \n\n**Signature:**\n\n```typescript\nclass ResultAsync<T, E> {\n  andTee(\n    callback: (value: T) => unknown\n  ): ResultAsync<T, E>  => { ... }\n}\n```\n\n**Example:**\n\n```typescript\nimport { insertUser } from 'imaginary-database'\nimport { logUser } from 'imaginary-logger'\nimport { sendNotification } from 'imaginary-service'\n\n// ^ assume insertUser, logUser and sendNotification have the following signatures:\n// insertUser(user: User): ResultAsync<User, InsertError>\n// logUser(user: User): Result<void, LogError>\n// sendNotification(user: User): ResultAsync<void, NotificationError>\n// Note logUser returns void on success but sendNotification takes User type. \n\nconst resAsync = insertUser(user)\n                .andTee(logUser)\n                .andThen(sendNotification)\n\n// Note there is no LogError in the types below \nresAsync.then((res: Result<void, InsertError | NotificationError>) => {\n  if(res.isErr()){\n    console.log(\"Oops, at least one step failed\", res.error)\n  }\n  else{\n    console.log(\"User has been inserted and notified successfully.\")\n  }\n})\n```\n\n[⬆️  Back to top](#toc)\n\n---\n#### `ResultAsync.orTee` (method)\n\nLike `andTee` for the error track. Takes a `ResultAsync<T, E>` and lets the original `Err` value pass through regardless \nthe result of the passed-in function.\nThis is a handy way to handle side effects whose failure or success should not affect your main logics such as logging. \n\n**Signature:**\n\n```typescript\nclass ResultAsync<T, E> {\n  orTee(\n    callback: (value: E) => unknown\n  ): ResultAsync<T, E>  => { ... }\n}\n```\n\n**Example:**\n\n```typescript\nimport { insertUser } from 'imaginary-database'\nimport { logInsertError } from 'imaginary-logger'\nimport { sendNotification } from 'imaginary-service'\n\n// ^ assume insertUser, logInsertError and sendNotification have the following signatures:\n// insertUser(user: User): ResultAsync<User, InsertError>\n// logInsertError(insertError: InsertError): Result<void, LogError>\n// sendNotification(user: User): ResultAsync<void, NotificationError>\n// Note logInsertError returns void on success but sendNotification takes User type. \n\nconst resAsync = insertUser(user)\n                .orTee(logInsertError)\n                .andThen(sendNotification)\n\n// Note there is no LogError in the types below \nresAsync.then((res: Result<void, InsertError | NotificationError>) => {\n  if(res.isErr()){\n    console.log(\"Oops, at least one step failed\", res.error)\n  }\n  else{\n    console.log(\"User has been inserted and notified successfully.\")\n  }\n})\n```\n\n[⬆️  Back to top](#toc)\n\n---\n#### `ResultAsync.andThrough` (method)\n\n\nSimilar to `andTee` except for:\n\n- when there is an error from the passed-in function, that error will be passed along.\n\n**Signature:**\n\n```typescript\nclass ResultAsync<T, E> {\n  andThrough<F>(\n    callback: (value: T) => Result<unknown, F> | ResultAsync<unknown, F>,\n  ): ResultAsync<T, E | F> => { ... }\n}\n```\n\n**Example:**\n\n```typescript\n\nimport { buildUser } from 'imaginary-builder'\nimport { insertUser } from 'imaginary-database'\nimport { sendNotification } from 'imaginary-service'\n\n// ^ assume buildUser, insertUser and sendNotification have the following signatures:\n// buildUser(userRaw: UserRaw): ResultAsync<User, BuildError>\n// insertUser(user: User): ResultAsync<void, InsertError>\n// sendNotification(user: User): ResultAsync<void, NotificationError>\n// Note insertUser returns void upon success but sendNotification takes User type. \n\nconst resAsync = buildUser(userRaw)\n                .andThrough(insertUser)\n                .andThen(sendNotification)\n\nresAsync.then((res: Result<void, BuildError | InsertError | NotificationError>) => {\n  if(res.isErr()){\n    console.log(\"Oops, at least one step failed\", res.error)\n  }\n  else{\n    console.log(\"User data has been built, inserted and notified successfully.\")\n  }\n})\n```\n\n[⬆️  Back to top](#toc)\n\n---\n#### `ResultAsync.combine` (static class method)\n\nCombine lists of `ResultAsync`s.\n\nIf you're familiar with `Promise.all`, the combine function works conceptually the same.\n\n**`combine` works on both heterogeneous and homogeneous lists**. This means that you can have lists that contain different kinds of `ResultAsync`s and still be able to combine them. Note that you cannot combine lists that contain both `Result`s **and** `ResultAsync`s.\n\nThe combine function takes a list of results and returns a single result. If all the results in the list are `Ok`, then the return value will be a `Ok` containing a list of all the individual `Ok` values.\n\nIf just one of the results in the list is an `Err` then the combine function returns that Err value (it short circuits and returns the first Err that it finds).\n\nFormally speaking:\n\n```typescript\n// homogeneous lists\nfunction combine<T, E>(resultList: ResultAsync<T, E>[]): ResultAsync<T[], E>\n\n// heterogeneous lists\nfunction combine<T1, T2, E1, E2>(resultList: [ ResultAsync<T1, E1>, ResultAsync<T2, E2> ]): ResultAsync<[ T1, T2 ], E1 | E2>\nfunction combine<T1, T2, T3, E1, E2, E3> => ResultAsync<[ T1, T2, T3 ], E1 | E2 | E3>\nfunction combine<T1, T2, T3, T4, E1, E2, E3, E4> => ResultAsync<[ T1, T2, T3, T4 ], E1 | E2 | E3 | E4>\n// ... etc etc ad infinitum\n\n```\n\nExample:\n```typescript\nconst resultList: ResultAsync<number, never>[] =\n  [okAsync(1), okAsync(2)]\n\nconst combinedList: ResultAsync<number[], unknown> =\n  ResultAsync.combine(resultList)\n```\n\nExample with tuples:\n```typescript\n/** @example tuple(1, 2, 3) === [1, 2, 3] // with type [number, number, number] */\nconst tuple = <T extends any[]>(...args: T): T => args\n\nconst resultTuple: [ResultAsync<string, never>, ResultAsync<string, never>] =\n  tuple(okAsync('a'), okAsync('b'))\n\nconst combinedTuple: ResultAsync<[string, string], unknown> =\n  ResultAsync.combine(resultTuple)\n```\n[⬆️  Back to top](#toc)\n\n---\n\n#### `ResultAsync.combineWithAllErrors` (static class method)\n\nLike `combine` but without short-circuiting. Instead of just the first error value, you get a list of all error values of the input result list.\n\nIf only some results fail, the new combined error list will only contain the error value of the failed results, meaning that there is no guarantee of the length of the new error list.\n\nFunction signature:\n\n```typescript\n// homogeneous lists\nfunction combineWithAllErrors<T, E>(resultList: ResultAsync<T, E>[]): ResultAsync<T[], E[]>\n\n// heterogeneous lists\nfunction combineWithAllErrors<T1, T2, E1, E2>(resultList: [ ResultAsync<T1, E1>, ResultAsync<T2, E2> ]): ResultAsync<[ T1, T2 ], (E1 | E2)[]>\nfunction combineWithAllErrors<T1, T2, T3, E1, E2, E3> => ResultAsync<[ T1, T2, T3 ], (E1 | E2 | E3)[]>\nfunction combineWithAllErrors<T1, T2, T3, T4, E1, E2, E3, E4> => ResultAsync<[ T1, T2, T3, T4 ], (E1 | E2 | E3 | E4)[]>\n// ... etc etc ad infinitum\n```\n\nExample usage:\n\n```typescript\nconst resultList: ResultAsync<number, string>[] = [\n  okAsync(123),\n  errAsync('boooom!'),\n  okAsync(456),\n  errAsync('ahhhhh!'),\n]\n\nconst result = ResultAsync.combineWithAllErrors(resultList)\n\n// result is Err(['boooom!', 'ahhhhh!'])\n```\n\n#### `ResultAsync.safeUnwrap()`\n\n**Deprecated**. You don't need to use this method anymore.\n\nAllows for unwrapping a `Result` or returning an `Err` implicitly, thereby reducing boilerplate.\n\n[⬆️  Back to top](#toc)\n\n---\n\n### Utilities\n\n#### `fromThrowable`\n\nTop level export of `Result.fromThrowable`.\nPlease find documentation at [Result.fromThrowable](#resultfromthrowable-static-class-method)\n\n[⬆️  Back to top](#toc)\n\n#### `fromAsyncThrowable`\n\nTop level export of `ResultAsync.fromThrowable`.\nPlease find documentation at [ResultAsync.fromThrowable](#resultasyncfromthrowable-static-class-method)\n\n[⬆️  Back to top](#toc)\n\n#### `fromPromise`\n\nTop level export of `ResultAsync.fromPromise`.\nPlease find documentation at [ResultAsync.fromPromise](#resultasyncfrompromise-static-class-method)\n\n[⬆️  Back to top](#toc)\n\n#### `fromSafePromise`\n\nTop level export of `ResultAsync.fromSafePromise`.\nPlease find documentation at [ResultAsync.fromSafePromise](#resultasyncfromsafepromise-static-class-method)\n\n[⬆️  Back to top](#toc)\n\n#### `safeTry`\n\nUsed to implicitly return errors and reduce boilerplate.\n\nLet's say we are writing a function that returns a `Result`, and in that function we call some functions which also return `Result`s and we check those results to see whether we should keep going or abort. Usually, we will write like the following.\n```typescript\ndeclare function mayFail1(): Result<number, string>;\ndeclare function mayFail2(): Result<number, string>;\n\nfunction myFunc(): Result<number, string> {\n    // We have to define a constant to hold the result to check and unwrap its value.\n    const result1 = mayFail1();\n    if (result1.isErr()) {\n        return err(`aborted by an error from 1st function, ${result1.error}`);\n    }\n    const value1 = result1.value\n\n    // Again, we need to define a constant and then check and unwrap.\n    const result2 = mayFail2();\n    if (result2.isErr()) {\n        return err(`aborted by an error from 2nd function, ${result2.error}`);\n    }\n    const value2 = result2.value\n\n    // And finally we return what we want to calculate\n    return ok(value1 + value2);\n}\n```\nBasically, we need to define a constant for each result to check whether it's a `Ok` and read its `.value` or `.error`.\n\nWith safeTry, we can state 'Return here if its an `Err`, otherwise unwrap it here and keep going.' in just one expression.\n```typescript\ndeclare function mayFail1(): Result<number, string>;\ndeclare function mayFail2(): Result<number, string>;\n\nfunction myFunc(): Result<number, string> {\n    return safeTry<number, string>(function*() {\n        return ok(\n            // If the result of mayFail1().mapErr() is an `Err`, the evaluation is\n            // aborted here and the enclosing `safeTry` block is evaluated to that `Err`.\n            // Otherwise, this `(yield* ...)` is evaluated to its `.value`.\n            (yield* mayFail1()\n                .mapErr(e => `aborted by an error from 1st function, ${e}`))\n            +\n            // The same as above.\n            (yield* mayFail2()\n                .mapErr(e => `aborted by an error from 2nd function, ${e}`))\n        )\n    })\n}\n```\n\nTo use `safeTry`, the points are as follows.\n* Wrap the entire block in a [generator function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*)\n* In that block, you can use `yield* <RESULT>` to state 'Return `<RESULT>` if it's an `Err`, otherwise evaluate to its `.value`'\n* Pass the generator function to `safeTry`\n\nYou can also use [async generator function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function*) to pass an async block to `safeTry`.\n```typescript\n// You can use either Promise<Result> or ResultAsync.\ndeclare function mayFail1(): Promise<Result<number, string>>;\ndeclare function mayFail2(): ResultAsync<number, string>;\n\nfunction myFunc(): Promise<Result<number, string>> {\n    return safeTry<number, string>(async function*() {\n        return ok(\n            // You have to await if the expression is Promise<Result>\n            (yield* (await mayFail1())\n                .mapErr(e => `aborted by an error from 1st function, ${e}`))\n            +\n            // You can call `safeUnwrap` directly if its ResultAsync\n            (yield* mayFail2()\n                .mapErr(e => `aborted by an error from 2nd function, ${e}`))\n        )\n    })\n}\n```\n\nFor more information, see https://github.com/supermacro/neverthrow/pull/448 and https://github.com/supermacro/neverthrow/issues/444\n\n[⬆️  Back to top](#toc)\n\n---\n\n### Testing\n\n`Result` instances have two unsafe methods, aptly called `_unsafeUnwrap` and `_unsafeUnwrapErr` which **should only be used in a test environment**.\n\n`_unsafeUnwrap` takes a `Result<T, E>` and returns a `T` when the result is an `Ok`, otherwise it throws a custom object.\n\n`_unsafeUnwrapErr` takes a `Result<T, E>` and returns a `E` when the result is an `Err`, otherwise it throws a custom object.\n\nThat way you can do something like:\n\n```typescript\nexpect(myResult._unsafeUnwrap()).toBe(someExpectation)\n```\n\nHowever, do note that `Result` instances are comparable. So you don't necessarily need to unwrap them in order to assert expectations in your tests. So you could also do something like this:\n\n```typescript\nimport { ok } from 'neverthrow'\n\n// ...\n\nexpect(callSomeFunctionThatReturnsAResult(\"with\", \"some\", \"args\")).toEqual(ok(someExpectation));\n```\n\nBy default, the thrown value does not contain a stack trace. This is because stack trace generation [makes error messages in Jest harder to understand](https://github.com/supermacro/neverthrow/pull/215). If you want stack traces to be generated, call `_unsafeUnwrap` and / or `_unsafeUnwrapErr` with a config object:\n\n```typescript\n_unsafeUnwrapErr({\n  withStackTrace: true,\n})\n\n// ^ Now the error object will have a `.stack` property containing the current stack\n```\n\n---\n\nIf you find this package useful, please consider [sponsoring me](https://github.com/sponsors/supermacro/) or simply [buying me a coffee](https://ko-fi.com/gdelgado)!\n\n---\n\n## A note on the Package Name\n\nAlthough the package is called `neverthrow`, please don't take this literally. I am simply encouraging the developer to think a bit more about the ergonomics and usage of whatever software they are writing.\n\n`Throw`ing and `catching` is very similar to using `goto` statements - in other words; it makes reasoning about your programs harder. Secondly, by using `throw` you make the assumption that the caller of your function is implementing `catch`. This is a known source of errors. Example: One dev `throw`s and another dev uses the function without prior knowledge that the function will throw. Thus, and edge case has been left unhandled and now you have unhappy users, bosses, cats, etc.\n\nWith all that said, there are definitely good use cases for throwing in your program. But much less than you might think.\n\n### License\n\nThe neverthrow project is available as open source under the terms of the [MIT license](https://github.com/supermacro/neverthrow/blob/master/LICENSE).\n"
  },
  {
    "path": "jest.config.js",
    "content": "module.exports = {\n  preset: 'ts-jest',\n  testEnvironment: 'node',\n};"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"neverthrow\",\n  \"version\": \"8.2.0\",\n  \"description\": \"Stop throwing errors, and instead return Results!\",\n  \"main\": \"dist/index.cjs.js\",\n  \"module\": \"dist/index.es.js\",\n  \"types\": \"dist/index.d.ts\",\n  \"files\": [\n    \"dist\"\n  ],\n  \"scripts\": {\n    \"local-ci\": \"npm run typecheck && npm run lint && npm run test && npm run format && npm run build\",\n    \"test\": \"vitest run && npm run test-types\",\n    \"test-types\": \"tsc --noEmit -p ./tests/tsconfig.tests.json\",\n    \"lint\": \"eslint ./src --ext .ts\",\n    \"format\": \"prettier --write 'src/**/*.ts?(x)' && npm run lint -- --fix\",\n    \"typecheck\": \"tsc --noEmit\",\n    \"clean\": \"rm -rf ./dist ./tmp\",\n    \"build\": \"npm run clean && rollup --config && mv tmp/*.js dist && attw --pack .\",\n    \"prepublishOnly\": \"npm run build\",\n    \"release\": \"changeset publish\",\n    \"version\": \"changeset version && npm i --lockfile-only\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/supermacro/neverthrow.git\"\n  },\n  \"author\": \"Giorgio Delgado\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/supermacro/neverthrow/issues\"\n  },\n  \"homepage\": \"https://github.com/supermacro/neverthrow#readme\",\n  \"devDependencies\": {\n    \"@arethetypeswrong/cli\": \"^0.17.3\",\n    \"@changesets/changelog-github\": \"^0.5.0\",\n    \"@changesets/cli\": \"^2.27.7\",\n    \"@types/node\": \"^18.19.39\",\n    \"@typescript-eslint/eslint-plugin\": \"4.28.1\",\n    \"@typescript-eslint/parser\": \"4.28.1\",\n    \"eslint\": \"7.30.0\",\n    \"eslint-config-prettier\": \"7.1.0\",\n    \"eslint-plugin-prettier\": \"3.4.0\",\n    \"prettier\": \"2.2.1\",\n    \"rollup\": \"^4.18.0\",\n    \"rollup-plugin-dts\": \"^6.1.1\",\n    \"rollup-plugin-typescript2\": \"^0.32.1\",\n    \"testdouble\": \"3.20.2\",\n    \"ts-toolbelt\": \"9.6.0\",\n    \"typescript\": \"4.7.2\",\n    \"vitest\": \"^2.1.3\"\n  },\n  \"keywords\": [\n    \"typescript\",\n    \"functional\",\n    \"fp\",\n    \"error\"\n  ],\n  \"engines\": {\n    \"node\": \">=18\",\n    \"npm\": \">=11\"\n  },\n  \"optionalDependencies\": {\n    \"@rollup/rollup-linux-x64-gnu\": \"^4.24.0\"\n  }\n}\n"
  },
  {
    "path": "rollup.config.mjs",
    "content": "import typescript from \"rollup-plugin-typescript2\";\nimport dts from \"rollup-plugin-dts\";\n\n/**\n * Just a few details about this build implementation:\n * - Uses `rollup` along with `rollup-plugin-typescript2` to build to two target files \n * (`index.es.js` and `index.cjs.js`). This means that there is only a *single* file now for each \n * target rather than 4 files (ie. `index.js`, `chain.js`, etc.).\n * - Rollup has their own official @rollup/plugin-typescript plugin but it does not have the best \n * TS declarations support atm (see https://github.com/rollup/plugins/issues/394, \n * https://github.com/rollup/plugins/issues/254, https://github.com/rollup/plugins/issues/243).\n * Until these are resolved, I choose to just use `rollup-plugin-typescript2`.\n * - `rollup-plugin-typescript2` generates `index.d.ts`, `chain.d.ts`, `result.d.ts` and \n * `result-async.d.ts` but this is inconsistent with the generated JavaScript files. This isn't a \n * huge issues unless someone tries to import `neverthrow/dist/chain` which would error \n * because the underlying `.js` doesn't exist. To remedy this issue, I used `rollup-plugin-dts` to \n * merge `*.d.ts` files into a single `index.d.ts`.\n * - It's unfortunately a bit complicated to generate two build outputs but once some of the \n * issues I've linked to above are resolved this process will become much easier :)\n * - Because the build process is kinda two steps (first using `rollup-plugin-typescript2` and then \n * using `rollup-plugin-dts`), I first write to `tmp/`, then write the merged `index.d.ts` to \n * `dist/` and then moved `index.es.js` and `index.cjs.js` to `dist/`.\n */\n\nexport default [\n  {\n    input: \"src/index.ts\",\n    output: {\n      file: \"tmp/index.es.js\",\n      format: \"es\",\n    },\n    plugins: [typescript()],\n  },\n  {\n    input: \"src/index.ts\",\n    output: {\n      file: \"tmp/index.cjs.js\",\n      format: \"cjs\",\n    },\n    plugins: [typescript()],\n  },\n  {\n    input: \"tmp/index.d.ts\",\n    output: [{ file: \"dist/index.d.ts\", format: \"es\" }],\n    plugins: [dts()],\n  },\n];\n"
  },
  {
    "path": "src/_internals/error.ts",
    "content": "import { Result } from '../result'\n\nexport interface ErrorConfig {\n  withStackTrace: boolean\n}\n\nconst defaultErrorConfig: ErrorConfig = {\n  withStackTrace: false,\n}\n\ninterface NeverThrowError<T, E> {\n  data:\n    | {\n        type: string\n        value: T\n      }\n    | {\n        type: string\n        value: E\n      }\n  message: string\n  stack: string | undefined\n}\n\n// Custom error object\n// Context / discussion: https://github.com/supermacro/neverthrow/pull/215\nexport const createNeverThrowError = <T, E>(\n  message: string,\n  result: Result<T, E>,\n  config: ErrorConfig = defaultErrorConfig,\n): NeverThrowError<T, E> => {\n  const data = result.isOk()\n    ? { type: 'Ok', value: result.value }\n    : { type: 'Err', value: result.error }\n\n  const maybeStack = config.withStackTrace ? new Error().stack : undefined\n\n  return {\n    data,\n    message,\n    stack: maybeStack,\n  }\n}\n"
  },
  {
    "path": "src/_internals/utils.ts",
    "content": "import { Result, ok, err } from '../result'\nimport { ResultAsync } from '../result-async'\n\n// Given a list of Results, this extracts all the different `T` types from that list\nexport type ExtractOkTypes<T extends readonly Result<unknown, unknown>[]> = {\n  [idx in keyof T]: T[idx] extends Result<infer U, unknown> ? U : never\n}\n\n// Given a list of ResultAsyncs, this extracts all the different `T` types from that list\nexport type ExtractOkAsyncTypes<T extends readonly ResultAsync<unknown, unknown>[]> = {\n  [idx in keyof T]: T[idx] extends ResultAsync<infer U, unknown> ? U : never\n}\n\n// Given a list of Results, this extracts all the different `E` types from that list\nexport type ExtractErrTypes<T extends readonly Result<unknown, unknown>[]> = {\n  [idx in keyof T]: T[idx] extends Result<unknown, infer E> ? E : never\n}\n\n// Given a list of ResultAsyncs, this extracts all the different `E` types from that list\nexport type ExtractErrAsyncTypes<T extends readonly ResultAsync<unknown, unknown>[]> = {\n  [idx in keyof T]: T[idx] extends ResultAsync<unknown, infer E> ? E : never\n}\n\nexport type InferOkTypes<R> = R extends Result<infer T, unknown> ? T : never\nexport type InferErrTypes<R> = R extends Result<unknown, infer E> ? E : never\n\nexport type InferAsyncOkTypes<R> = R extends ResultAsync<infer T, unknown> ? T : never\nexport type InferAsyncErrTypes<R> = R extends ResultAsync<unknown, infer E> ? E : never\n\n/**\n * Short circuits on the FIRST Err value that we find\n */\nexport const combineResultList = <T, E>(\n  resultList: readonly Result<T, E>[],\n): Result<readonly T[], E> => {\n  let acc = ok([]) as Result<T[], E>\n\n  for (const result of resultList) {\n    if (result.isErr()) {\n      acc = err(result.error)\n      break\n    } else {\n      acc.map((list) => list.push(result.value))\n    }\n  }\n  return acc\n}\n\n/* This is the typesafe version of Promise.all\n *\n * Takes a list of ResultAsync<T, E> and success if all inner results are Ok values\n * or fails if one (or more) of the inner results are Err values\n */\nexport const combineResultAsyncList = <T, E>(\n  asyncResultList: readonly ResultAsync<T, E>[],\n): ResultAsync<readonly T[], E> =>\n  ResultAsync.fromSafePromise(Promise.all(asyncResultList)).andThen(\n    combineResultList,\n  ) as ResultAsync<T[], E>\n\n/**\n * Give a list of all the errors we find\n */\nexport const combineResultListWithAllErrors = <T, E>(\n  resultList: readonly Result<T, E>[],\n): Result<readonly T[], E[]> => {\n  let acc = ok([]) as Result<T[], E[]>\n\n  for (const result of resultList) {\n    if (result.isErr() && acc.isErr()) {\n      acc.error.push(result.error)\n    } else if (result.isErr() && acc.isOk()) {\n      acc = err([result.error])\n    } else if (result.isOk() && acc.isOk()) {\n      acc.value.push(result.value)\n    }\n    // do nothing when result.isOk() && acc.isErr()\n  }\n  return acc\n}\n\nexport const combineResultAsyncListWithAllErrors = <T, E>(\n  asyncResultList: readonly ResultAsync<T, E>[],\n): ResultAsync<readonly T[], E[]> =>\n  ResultAsync.fromSafePromise(Promise.all(asyncResultList)).andThen(\n    combineResultListWithAllErrors,\n  ) as ResultAsync<T[], E[]>\n"
  },
  {
    "path": "src/index.ts",
    "content": "export { Result, ok, Ok, err, Err, fromThrowable, safeTry } from './result'\nexport {\n  ResultAsync,\n  okAsync,\n  errAsync,\n  fromAsyncThrowable,\n  fromPromise,\n  fromSafePromise,\n} from './result-async'\n"
  },
  {
    "path": "src/result-async.ts",
    "content": "import type {\n  Combine,\n  Dedup,\n  EmptyArrayToNever,\n  IsLiteralArray,\n  MemberListOf,\n  MembersToUnion,\n} from './result'\n\nimport { Err, Ok, Result } from './'\nimport {\n  combineResultAsyncList,\n  combineResultAsyncListWithAllErrors,\n  ExtractErrAsyncTypes,\n  ExtractOkAsyncTypes,\n  InferAsyncErrTypes,\n  InferAsyncOkTypes,\n  InferErrTypes,\n  InferOkTypes,\n} from './_internals/utils'\n\nexport class ResultAsync<T, E> implements PromiseLike<Result<T, E>> {\n  private _promise: Promise<Result<T, E>>\n\n  constructor(res: Promise<Result<T, E>>) {\n    this._promise = res\n  }\n\n  static fromSafePromise<T, E = never>(promise: PromiseLike<T>): ResultAsync<T, E>\n  static fromSafePromise<T, E = never>(promise: Promise<T>): ResultAsync<T, E> {\n    const newPromise = promise.then((value: T) => new Ok<T, E>(value))\n\n    return new ResultAsync(newPromise)\n  }\n\n  static fromPromise<T, E>(promise: PromiseLike<T>, errorFn: (e: unknown) => E): ResultAsync<T, E>\n  static fromPromise<T, E>(promise: Promise<T>, errorFn: (e: unknown) => E): ResultAsync<T, E> {\n    const newPromise = promise\n      .then((value: T) => new Ok<T, E>(value))\n      .catch((e) => new Err<T, E>(errorFn(e)))\n\n    return new ResultAsync(newPromise)\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  static fromThrowable<A extends readonly any[], R, E>(\n    fn: (...args: A) => Promise<R>,\n    errorFn?: (err: unknown) => E,\n  ): (...args: A) => ResultAsync<R, E> {\n    return (...args) => {\n      return new ResultAsync(\n        (async () => {\n          try {\n            return new Ok(await fn(...args))\n          } catch (error) {\n            return new Err(errorFn ? errorFn(error) : error)\n          }\n        })(),\n      )\n    }\n  }\n\n  static combine<\n    T extends readonly [ResultAsync<unknown, unknown>, ...ResultAsync<unknown, unknown>[]]\n  >(asyncResultList: T): CombineResultAsyncs<T>\n  static combine<T extends readonly ResultAsync<unknown, unknown>[]>(\n    asyncResultList: T,\n  ): CombineResultAsyncs<T>\n  static combine<T extends readonly ResultAsync<unknown, unknown>[]>(\n    asyncResultList: T,\n  ): CombineResultAsyncs<T> {\n    return (combineResultAsyncList(asyncResultList) as unknown) as CombineResultAsyncs<T>\n  }\n\n  static combineWithAllErrors<\n    T extends readonly [ResultAsync<unknown, unknown>, ...ResultAsync<unknown, unknown>[]]\n  >(asyncResultList: T): CombineResultsWithAllErrorsArrayAsync<T>\n  static combineWithAllErrors<T extends readonly ResultAsync<unknown, unknown>[]>(\n    asyncResultList: T,\n  ): CombineResultsWithAllErrorsArrayAsync<T>\n  static combineWithAllErrors<T extends readonly ResultAsync<unknown, unknown>[]>(\n    asyncResultList: T,\n  ): CombineResultsWithAllErrorsArrayAsync<T> {\n    return combineResultAsyncListWithAllErrors(\n      asyncResultList,\n    ) as CombineResultsWithAllErrorsArrayAsync<T>\n  }\n\n  map<A>(f: (t: T) => A | Promise<A>): ResultAsync<A, E> {\n    return new ResultAsync(\n      this._promise.then(async (res: Result<T, E>) => {\n        if (res.isErr()) {\n          return new Err<A, E>(res.error)\n        }\n\n        return new Ok<A, E>(await f(res.value))\n      }),\n    )\n  }\n\n  andThrough<F>(f: (t: T) => Result<unknown, F> | ResultAsync<unknown, F>): ResultAsync<T, E | F> {\n    return new ResultAsync(\n      this._promise.then(async (res: Result<T, E>) => {\n        if (res.isErr()) {\n          return new Err<T, E>(res.error)\n        }\n\n        const newRes = await f(res.value)\n        if (newRes.isErr()) {\n          return new Err<T, F>(newRes.error)\n        }\n        return new Ok<T, F>(res.value)\n      }),\n    )\n  }\n\n  andTee(f: (t: T) => unknown): ResultAsync<T, E> {\n    return new ResultAsync(\n      this._promise.then(async (res: Result<T, E>) => {\n        if (res.isErr()) {\n          return new Err<T, E>(res.error)\n        }\n        try {\n          await f(res.value)\n        } catch (e) {\n          // Tee does not care about the error\n        }\n        return new Ok<T, E>(res.value)\n      }),\n    )\n  }\n\n  orTee(f: (t: E) => unknown): ResultAsync<T, E> {\n    return new ResultAsync(\n      this._promise.then(async (res: Result<T, E>) => {\n        if (res.isOk()) {\n          return new Ok<T, E>(res.value)\n        }\n        try {\n          await f(res.error)\n        } catch (e) {\n          // Tee does not care about the error\n        }\n        return new Err<T, E>(res.error)\n      }),\n    )\n  }\n\n  mapErr<U>(f: (e: E) => U | Promise<U>): ResultAsync<T, U> {\n    return new ResultAsync(\n      this._promise.then(async (res: Result<T, E>) => {\n        if (res.isOk()) {\n          return new Ok<T, U>(res.value)\n        }\n\n        return new Err<T, U>(await f(res.error))\n      }),\n    )\n  }\n\n  andThen<R extends Result<unknown, unknown>>(\n    f: (t: T) => R,\n  ): ResultAsync<InferOkTypes<R>, InferErrTypes<R> | E>\n  andThen<R extends ResultAsync<unknown, unknown>>(\n    f: (t: T) => R,\n  ): ResultAsync<InferAsyncOkTypes<R>, InferAsyncErrTypes<R> | E>\n  andThen<U, F>(f: (t: T) => Result<U, F> | ResultAsync<U, F>): ResultAsync<U, E | F>\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n  andThen(f: any): any {\n    return new ResultAsync(\n      this._promise.then((res) => {\n        if (res.isErr()) {\n          return new Err<never, E>(res.error)\n        }\n\n        const newValue = f(res.value)\n        return newValue instanceof ResultAsync ? newValue._promise : newValue\n      }),\n    )\n  }\n\n  orElse<R extends Result<unknown, unknown>>(\n    f: (e: E) => R,\n  ): ResultAsync<InferOkTypes<R> | T, InferErrTypes<R>>\n  orElse<R extends ResultAsync<unknown, unknown>>(\n    f: (e: E) => R,\n  ): ResultAsync<InferAsyncOkTypes<R> | T, InferAsyncErrTypes<R>>\n  orElse<U, A>(f: (e: E) => Result<U, A> | ResultAsync<U, A>): ResultAsync<U | T, A>\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n  orElse(f: any): any {\n    return new ResultAsync(\n      this._promise.then(async (res: Result<T, E>) => {\n        if (res.isErr()) {\n          return f(res.error)\n        }\n\n        return new Ok<T, unknown>(res.value)\n      }),\n    )\n  }\n\n  match<A, B = A>(ok: (t: T) => A, _err: (e: E) => B): Promise<A | B> {\n    return this._promise.then((res) => res.match(ok, _err))\n  }\n\n  unwrapOr<A>(t: A): Promise<T | A> {\n    return this._promise.then((res) => res.unwrapOr(t))\n  }\n\n  /**\n   * @deprecated will be removed in 9.0.0.\n   *\n   * You can use `safeTry` without this method.\n   * @example\n   * ```typescript\n   * safeTry(async function* () {\n   *   const okValue = yield* yourResult\n   * })\n   * ```\n   * Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.\n   */\n  async *safeUnwrap(): AsyncGenerator<Err<never, E>, T> {\n    return yield* await this._promise.then((res) => res.safeUnwrap())\n  }\n\n  // Makes ResultAsync implement PromiseLike<Result>\n  then<A, B>(\n    successCallback?: (res: Result<T, E>) => A | PromiseLike<A>,\n    failureCallback?: (reason: unknown) => B | PromiseLike<B>,\n  ): PromiseLike<A | B> {\n    return this._promise.then(successCallback, failureCallback)\n  }\n\n  async *[Symbol.asyncIterator](): AsyncGenerator<Err<never, E>, T> {\n    const result = await this._promise\n\n    if (result.isErr()) {\n      // @ts-expect-error -- This is structurally equivalent and safe\n      yield errAsync(result.error)\n    }\n\n    // @ts-expect-error -- This is structurally equivalent and safe\n    return result.value\n  }\n}\n\nexport function okAsync<T, E = never>(value: T): ResultAsync<T, E>\nexport function okAsync<T extends void = void, E = never>(value: void): ResultAsync<void, E>\nexport function okAsync<T, E = never>(value: T): ResultAsync<T, E> {\n  return new ResultAsync(Promise.resolve(new Ok<T, E>(value)))\n}\n\nexport function errAsync<T = never, E = unknown>(err: E): ResultAsync<T, E>\nexport function errAsync<T = never, E extends void = void>(err: void): ResultAsync<T, void>\nexport function errAsync<T = never, E = unknown>(err: E): ResultAsync<T, E> {\n  return new ResultAsync(Promise.resolve(new Err<T, E>(err)))\n}\n\nexport const fromPromise = ResultAsync.fromPromise\nexport const fromSafePromise = ResultAsync.fromSafePromise\n\nexport const fromAsyncThrowable = ResultAsync.fromThrowable\n\n// Combines the array of async results into one result.\nexport type CombineResultAsyncs<\n  T extends readonly ResultAsync<unknown, unknown>[]\n> = IsLiteralArray<T> extends 1\n  ? TraverseAsync<UnwrapAsync<T>>\n  : ResultAsync<ExtractOkAsyncTypes<T>, ExtractErrAsyncTypes<T>[number]>\n\n// Combines the array of async results into one result with all errors.\nexport type CombineResultsWithAllErrorsArrayAsync<\n  T extends readonly ResultAsync<unknown, unknown>[]\n> = IsLiteralArray<T> extends 1\n  ? TraverseWithAllErrorsAsync<UnwrapAsync<T>>\n  : ResultAsync<ExtractOkAsyncTypes<T>, ExtractErrAsyncTypes<T>[number][]>\n\n// Unwraps the inner `Result` from a `ResultAsync` for all elements.\ntype UnwrapAsync<T> = IsLiteralArray<T> extends 1\n  ? Writable<T> extends [infer H, ...infer Rest]\n    ? H extends PromiseLike<infer HI>\n      ? HI extends Result<unknown, unknown>\n        ? [Dedup<HI>, ...UnwrapAsync<Rest>]\n        : never\n      : never\n    : []\n  : // If we got something too general such as ResultAsync<X, Y>[] then we\n  // simply need to map it to ResultAsync<X[], Y[]>. Yet `ResultAsync`\n  // itself is a union therefore it would be enough to cast it to Ok.\n  T extends Array<infer A>\n  ? A extends PromiseLike<infer HI>\n    ? HI extends Result<infer L, infer R>\n      ? Ok<L, R>[]\n      : never\n    : never\n  : never\n\n// Traverse through the tuples of the async results and create one\n// `ResultAsync` where the collected tuples are merged.\ntype TraverseAsync<T, Depth extends number = 5> = IsLiteralArray<T> extends 1\n  ? Combine<T, Depth> extends [infer Oks, infer Errs]\n    ? ResultAsync<EmptyArrayToNever<Oks>, MembersToUnion<Errs>>\n    : never\n  : // The following check is important if we somehow reach to the point of\n  // checking something similar to ResultAsync<X, Y>[]. In this case we don't\n  // know the length of the elements, therefore we need to traverse the X and Y\n  // in a way that the result should contain X[] and Y[].\n  T extends Array<infer I>\n  ? // The MemberListOf<I> here is to include all possible types. Therefore\n    // if we face (ResultAsync<X, Y> | ResultAsync<A, B>)[] this type should\n    // handle the case.\n    Combine<MemberListOf<I>, Depth> extends [infer Oks, infer Errs]\n    ? // The following `extends unknown[]` checks are just to satisfy the TS.\n      // we already expect them to be an array.\n      Oks extends unknown[]\n      ? Errs extends unknown[]\n        ? ResultAsync<EmptyArrayToNever<Oks[number][]>, MembersToUnion<Errs[number][]>>\n        : ResultAsync<EmptyArrayToNever<Oks[number][]>, Errs>\n      : // The rest of the conditions are to satisfy the TS and support\n      // the edge cases which are not really expected to happen.\n      Errs extends unknown[]\n      ? ResultAsync<Oks, MembersToUnion<Errs[number][]>>\n      : ResultAsync<Oks, Errs>\n    : never\n  : never\n\n// This type is similar to the `TraverseAsync` while the errors are also\n// collected in a list. For the checks/conditions made here, see that type\n// for the documentation.\ntype TraverseWithAllErrorsAsync<T, Depth extends number = 5> = TraverseAsync<\n  T,\n  Depth\n> extends ResultAsync<infer Oks, infer Errs>\n  ? ResultAsync<Oks, Errs[]>\n  : never\n\n// Converts a reaodnly array into a writable array\ntype Writable<T> = T extends ReadonlyArray<unknown> ? [...T] : T\n"
  },
  {
    "path": "src/result.ts",
    "content": "import { errAsync, ResultAsync } from './'\nimport { createNeverThrowError, ErrorConfig } from './_internals/error'\nimport {\n  combineResultList,\n  combineResultListWithAllErrors,\n  ExtractErrTypes,\n  ExtractOkTypes,\n  InferAsyncErrTypes,\n  InferErrTypes,\n  InferOkTypes,\n} from './_internals/utils'\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace Result {\n  /**\n   * Wraps a function with a try catch, creating a new function with the same\n   * arguments but returning `Ok` if successful, `Err` if the function throws\n   *\n   * @param fn function to wrap with ok on success or err on failure\n   * @param errorFn when an error is thrown, this will wrap the error result if provided\n   */\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  export function fromThrowable<Fn extends (...args: readonly any[]) => any, E>(\n    fn: Fn,\n    errorFn?: (e: unknown) => E,\n  ): (...args: Parameters<Fn>) => Result<ReturnType<Fn>, E> {\n    return (...args) => {\n      try {\n        const result = fn(...args)\n        return ok(result)\n      } catch (e) {\n        return err(errorFn ? errorFn(e) : e)\n      }\n    }\n  }\n\n  export function combine<\n    T extends readonly [Result<unknown, unknown>, ...Result<unknown, unknown>[]]\n  >(resultList: T): CombineResults<T>\n  export function combine<T extends readonly Result<unknown, unknown>[]>(\n    resultList: T,\n  ): CombineResults<T>\n  export function combine<\n    T extends readonly [Result<unknown, unknown>, ...Result<unknown, unknown>[]]\n  >(resultList: T): CombineResults<T> {\n    return combineResultList(resultList) as CombineResults<T>\n  }\n\n  export function combineWithAllErrors<\n    T extends readonly [Result<unknown, unknown>, ...Result<unknown, unknown>[]]\n  >(resultList: T): CombineResultsWithAllErrorsArray<T>\n  export function combineWithAllErrors<T extends readonly Result<unknown, unknown>[]>(\n    resultList: T,\n  ): CombineResultsWithAllErrorsArray<T>\n  export function combineWithAllErrors<T extends readonly Result<unknown, unknown>[]>(\n    resultList: T,\n  ): CombineResultsWithAllErrorsArray<T> {\n    return combineResultListWithAllErrors(resultList) as CombineResultsWithAllErrorsArray<T>\n  }\n}\n\nexport type Result<T, E> = Ok<T, E> | Err<T, E>\n\nexport function ok<T, E = never>(value: T): Ok<T, E>\nexport function ok<T extends void = void, E = never>(value: void): Ok<void, E>\nexport function ok<T, E = never>(value: T): Ok<T, E> {\n  return new Ok(value)\n}\n\nexport function err<T = never, E extends string = string>(err: E): Err<T, E>\nexport function err<T = never, E = unknown>(err: E): Err<T, E>\nexport function err<T = never, E extends void = void>(err: void): Err<T, void>\nexport function err<T = never, E = unknown>(err: E): Err<T, E> {\n  return new Err(err)\n}\n\n/**\n * Evaluates the given generator to a Result returned or an Err yielded from it,\n * whichever comes first.\n *\n * This function is intended to emulate Rust's ? operator.\n * See `/tests/safeTry.test.ts` for examples.\n *\n * @param body - What is evaluated. In body, `yield* result` works as\n * Rust's `result?` expression.\n * @returns The first occurrence of either an yielded Err or a returned Result.\n */\nexport function safeTry<T, E>(body: () => Generator<Err<never, E>, Result<T, E>>): Result<T, E>\nexport function safeTry<\n  YieldErr extends Err<never, unknown>,\n  GeneratorReturnResult extends Result<unknown, unknown>\n>(\n  body: () => Generator<YieldErr, GeneratorReturnResult>,\n): Result<\n  InferOkTypes<GeneratorReturnResult>,\n  InferErrTypes<YieldErr> | InferErrTypes<GeneratorReturnResult>\n>\n\n/**\n * Evaluates the given generator to a Result returned or an Err yielded from it,\n * whichever comes first.\n *\n * This function is intended to emulate Rust's ? operator.\n * See `/tests/safeTry.test.ts` for examples.\n *\n * @param body - What is evaluated. In body, `yield* result` and\n * `yield* resultAsync` work as Rust's `result?` expression.\n * @returns The first occurrence of either an yielded Err or a returned Result.\n */\nexport function safeTry<T, E>(\n  body: () => AsyncGenerator<Err<never, E>, Result<T, E>>,\n): ResultAsync<T, E>\nexport function safeTry<\n  YieldErr extends Err<never, unknown>,\n  GeneratorReturnResult extends Result<unknown, unknown>\n>(\n  body: () => AsyncGenerator<YieldErr, GeneratorReturnResult>,\n): ResultAsync<\n  InferOkTypes<GeneratorReturnResult>,\n  InferErrTypes<YieldErr> | InferErrTypes<GeneratorReturnResult>\n>\nexport function safeTry<T, E>(\n  body:\n    | (() => Generator<Err<never, E>, Result<T, E>>)\n    | (() => AsyncGenerator<Err<never, E>, Result<T, E>>),\n): Result<T, E> | ResultAsync<T, E> {\n  const n = body().next()\n  if (n instanceof Promise) {\n    return new ResultAsync(n.then((r) => r.value))\n  }\n  return n.value\n}\n\ninterface IResult<T, E> {\n  /**\n   * Used to check if a `Result` is an `OK`\n   *\n   * @returns `true` if the result is an `OK` variant of Result\n   */\n  isOk(): this is Ok<T, E>\n\n  /**\n   * Used to check if a `Result` is an `Err`\n   *\n   * @returns `true` if the result is an `Err` variant of Result\n   */\n  isErr(): this is Err<T, E>\n\n  /**\n   * Maps a `Result<T, E>` to `Result<U, E>`\n   * by applying a function to a contained `Ok` value, leaving an `Err` value\n   * untouched.\n   *\n   * @param f The function to apply an `OK` value\n   * @returns the result of applying `f` or an `Err` untouched\n   */\n  map<A>(f: (t: T) => A): Result<A, E>\n\n  /**\n   * Maps a `Result<T, E>` to `Result<T, F>` by applying a function to a\n   * contained `Err` value, leaving an `Ok` value untouched.\n   *\n   * This function can be used to pass through a successful result while\n   * handling an error.\n   *\n   * @param f a function to apply to the error `Err` value\n   */\n  mapErr<U>(f: (e: E) => U): Result<T, U>\n\n  /**\n   * Similar to `map` Except you must return a new `Result`.\n   *\n   * This is useful for when you need to do a subsequent computation using the\n   * inner `T` value, but that computation might fail.\n   * Additionally, `andThen` is really useful as a tool to flatten a\n   * `Result<Result<A, E2>, E1>` into a `Result<A, E2>` (see example below).\n   *\n   * @param f The function to apply to the current value\n   */\n  andThen<R extends Result<unknown, unknown>>(\n    f: (t: T) => R,\n  ): Result<InferOkTypes<R>, InferErrTypes<R> | E>\n  andThen<U, F>(f: (t: T) => Result<U, F>): Result<U, E | F>\n\n  /**\n   * This \"tee\"s the current value to an passed-in computation such as side\n   * effect functions but still returns the same current value as the result.\n   *\n   * This is useful when you want to pass the current result to your side-track\n   * work such as logging but want to continue main-track work after that.\n   * This method does not care about the result of the passed in computation.\n   *\n   * @param f The function to apply to the current value\n   */\n  andTee(f: (t: T) => unknown): Result<T, E>\n\n  /**\n   * This \"tee\"s the current `Err` value to an passed-in computation such as side\n   * effect functions but still returns the same `Err` value as the result.\n   *\n   * This is useful when you want to pass the current `Err` value to your side-track\n   * work such as logging but want to continue error-track work after that.\n   * This method does not care about the result of the passed in computation.\n   *\n   * @param f The function to apply to the current `Err` value\n   */\n  orTee(f: (t: E) => unknown): Result<T, E>\n\n  /**\n   * Similar to `andTee` except error result of the computation will be passed\n   * to the downstream in case of an error.\n   *\n   * This version is useful when you want to make side-effects but in case of an\n   * error, you want to pass the error to the downstream.\n   *\n   * @param f The function to apply to the current value\n   */\n  andThrough<R extends Result<unknown, unknown>>(f: (t: T) => R): Result<T, InferErrTypes<R> | E>\n  andThrough<F>(f: (t: T) => Result<unknown, F>): Result<T, E | F>\n\n  /**\n   * Takes an `Err` value and maps it to a `Result<T, SomeNewType>`.\n   *\n   * This is useful for error recovery.\n   *\n   *\n   * @param f  A function to apply to an `Err` value, leaving `Ok` values\n   * untouched.\n   */\n  orElse<R extends Result<unknown, unknown>>(\n    f: (e: E) => R,\n  ): Result<InferOkTypes<R> | T, InferErrTypes<R>>\n  orElse<U, A>(f: (e: E) => Result<U, A>): Result<U | T, A>\n\n  /**\n   * Similar to `map` Except you must return a new `Result`.\n   *\n   * This is useful for when you need to do a subsequent async computation using\n   * the inner `T` value, but that computation might fail. Must return a ResultAsync\n   *\n   * @param f The function that returns a `ResultAsync` to apply to the current\n   * value\n   */\n  asyncAndThen<U, F>(f: (t: T) => ResultAsync<U, F>): ResultAsync<U, E | F>\n\n  /**\n   * Maps a `Result<T, E>` to `ResultAsync<U, E>`\n   * by applying an async function to a contained `Ok` value, leaving an `Err`\n   * value untouched.\n   *\n   * @param f An async function to apply an `OK` value\n   */\n  asyncMap<U>(f: (t: T) => Promise<U>): ResultAsync<U, E>\n\n  /**\n   * Unwrap the `Ok` value, or return the default if there is an `Err`\n   *\n   * @param v the default value to return if there is an `Err`\n   */\n  unwrapOr<A>(v: A): T | A\n\n  /**\n   *\n   * Given 2 functions (one for the `Ok` variant and one for the `Err` variant)\n   * execute the function that matches the `Result` variant.\n   *\n   * Match callbacks do not necessitate to return a `Result`, however you can\n   * return a `Result` if you want to.\n   *\n   * `match` is like chaining `map` and `mapErr`, with the distinction that\n   * with `match` both functions must have the same return type.\n   *\n   * @param ok\n   * @param err\n   */\n  match<A, B = A>(ok: (t: T) => A, err: (e: E) => B): A | B\n\n  /**\n   * @deprecated will be removed in 9.0.0.\n   *\n   * You can use `safeTry` without this method.\n   * @example\n   * ```typescript\n   * safeTry(function* () {\n   *   const okValue = yield* yourResult\n   * })\n   * ```\n   * Emulates Rust's `?` operator in `safeTry`'s body. See also `safeTry`.\n   */\n  safeUnwrap(): Generator<Err<never, E>, T>\n\n  /**\n   * **This method is unsafe, and should only be used in a test environments**\n   *\n   * Takes a `Result<T, E>` and returns a `T` when the result is an `Ok`, otherwise it throws a custom object.\n   *\n   * @param config\n   */\n  _unsafeUnwrap(config?: ErrorConfig): T\n\n  /**\n   * **This method is unsafe, and should only be used in a test environments**\n   *\n   * takes a `Result<T, E>` and returns a `E` when the result is an `Err`,\n   * otherwise it throws a custom object.\n   *\n   * @param config\n   */\n  _unsafeUnwrapErr(config?: ErrorConfig): E\n}\n\nexport class Ok<T, E> implements IResult<T, E> {\n  constructor(readonly value: T) {}\n\n  isOk(): this is Ok<T, E> {\n    return true\n  }\n\n  isErr(): this is Err<T, E> {\n    return !this.isOk()\n  }\n\n  map<A>(f: (t: T) => A): Result<A, E> {\n    return ok(f(this.value))\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  mapErr<U>(_f: (e: E) => U): Result<T, U> {\n    return ok(this.value)\n  }\n\n  andThen<R extends Result<unknown, unknown>>(\n    f: (t: T) => R,\n  ): Result<InferOkTypes<R>, InferErrTypes<R> | E>\n  andThen<U, F>(f: (t: T) => Result<U, F>): Result<U, E | F>\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n  andThen(f: any): any {\n    return f(this.value)\n  }\n\n  andThrough<R extends Result<unknown, unknown>>(f: (t: T) => R): Result<T, InferErrTypes<R> | E>\n  andThrough<F>(f: (t: T) => Result<unknown, F>): Result<T, E | F>\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n  andThrough(f: any): any {\n    return f(this.value).map((_value: unknown) => this.value)\n  }\n\n  andTee(f: (t: T) => unknown): Result<T, E> {\n    try {\n      f(this.value)\n    } catch (e) {\n      // Tee doesn't care about the error\n    }\n    return ok<T, E>(this.value)\n  }\n\n  orTee(_f: (t: E) => unknown): Result<T, E> {\n    return ok<T, E>(this.value)\n  }\n\n  orElse<R extends Result<unknown, unknown>>(\n    _f: (e: E) => R,\n  ): Result<InferOkTypes<R> | T, InferErrTypes<R>>\n  orElse<U, A>(_f: (e: E) => Result<U, A>): Result<U | T, A>\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n  orElse(_f: any): any {\n    return ok(this.value)\n  }\n\n  asyncAndThen<U, F>(f: (t: T) => ResultAsync<U, F>): ResultAsync<U, E | F> {\n    return f(this.value)\n  }\n\n  asyncAndThrough<R extends ResultAsync<unknown, unknown>>(\n    f: (t: T) => R,\n  ): ResultAsync<T, InferAsyncErrTypes<R> | E>\n  asyncAndThrough<F>(f: (t: T) => ResultAsync<unknown, F>): ResultAsync<T, E | F>\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n  asyncAndThrough(f: (t: T) => ResultAsync<unknown, unknown>): any {\n    return f(this.value).map(() => this.value)\n  }\n\n  asyncMap<U>(f: (t: T) => Promise<U>): ResultAsync<U, E> {\n    return ResultAsync.fromSafePromise(f(this.value))\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  unwrapOr<A>(_v: A): T | A {\n    return this.value\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  match<A, B = A>(ok: (t: T) => A, _err: (e: E) => B): A | B {\n    return ok(this.value)\n  }\n\n  safeUnwrap(): Generator<Err<never, E>, T> {\n    const value = this.value\n    /* eslint-disable-next-line require-yield */\n    return (function* () {\n      return value\n    })()\n  }\n\n  _unsafeUnwrap(_?: ErrorConfig): T {\n    return this.value\n  }\n\n  _unsafeUnwrapErr(config?: ErrorConfig): E {\n    throw createNeverThrowError('Called `_unsafeUnwrapErr` on an Ok', this, config)\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-this-alias, require-yield\n  *[Symbol.iterator](): Generator<Err<never, E>, T> {\n    return this.value\n  }\n}\n\nexport class Err<T, E> implements IResult<T, E> {\n  constructor(readonly error: E) {}\n\n  isOk(): this is Ok<T, E> {\n    return false\n  }\n\n  isErr(): this is Err<T, E> {\n    return !this.isOk()\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  map<A>(_f: (t: T) => A): Result<A, E> {\n    return err(this.error)\n  }\n\n  mapErr<U>(f: (e: E) => U): Result<T, U> {\n    return err(f(this.error))\n  }\n\n  andThrough<F>(_f: (t: T) => Result<unknown, F>): Result<T, E | F> {\n    return err(this.error)\n  }\n\n  andTee(_f: (t: T) => unknown): Result<T, E> {\n    return err(this.error)\n  }\n\n  orTee(f: (t: E) => unknown): Result<T, E> {\n    try {\n      f(this.error)\n    } catch (e) {\n      // Tee doesn't care about the error\n    }\n    return err<T, E>(this.error)\n  }\n\n  andThen<R extends Result<unknown, unknown>>(\n    _f: (t: T) => R,\n  ): Result<InferOkTypes<R>, InferErrTypes<R> | E>\n  andThen<U, F>(_f: (t: T) => Result<U, F>): Result<U, E | F>\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n  andThen(_f: any): any {\n    return err(this.error)\n  }\n\n  orElse<R extends Result<unknown, unknown>>(\n    f: (e: E) => R,\n  ): Result<InferOkTypes<R> | T, InferErrTypes<R>>\n  orElse<U, A>(f: (e: E) => Result<U, A>): Result<U | T, A>\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types\n  orElse(f: any): any {\n    return f(this.error)\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  asyncAndThen<U, F>(_f: (t: T) => ResultAsync<U, F>): ResultAsync<U, E | F> {\n    return errAsync<U, E>(this.error)\n  }\n\n  asyncAndThrough<F>(_f: (t: T) => ResultAsync<unknown, F>): ResultAsync<T, E | F> {\n    return errAsync<T, E>(this.error)\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  asyncMap<U>(_f: (t: T) => Promise<U>): ResultAsync<U, E> {\n    return errAsync<U, E>(this.error)\n  }\n\n  unwrapOr<A>(v: A): T | A {\n    return v\n  }\n\n  match<A, B = A>(_ok: (t: T) => A, err: (e: E) => B): A | B {\n    return err(this.error)\n  }\n\n  safeUnwrap(): Generator<Err<never, E>, T> {\n    const error = this.error\n    return (function* () {\n      yield err(error)\n\n      throw new Error('Do not use this generator out of `safeTry`')\n    })()\n  }\n\n  _unsafeUnwrap(config?: ErrorConfig): T {\n    throw createNeverThrowError('Called `_unsafeUnwrap` on an Err', this, config)\n  }\n\n  _unsafeUnwrapErr(_?: ErrorConfig): E {\n    return this.error\n  }\n\n  *[Symbol.iterator](): Generator<Err<never, E>, T> {\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    const self = this\n    // @ts-expect-error -- This is structurally equivalent and safe\n    yield self\n    // @ts-expect-error -- This is structurally equivalent and safe\n    return self\n  }\n}\n\nexport const fromThrowable = Result.fromThrowable\n\n//#region Combine - Types\n\n// This is a helper type to prevent infinite recursion in typing rules.\n//\n// Use this with your `depth` variable in your types.\ntype Prev = [\n  never,\n  0,\n  1,\n  2,\n  3,\n  4,\n  5,\n  6,\n  7,\n  8,\n  9,\n  10,\n  11,\n  12,\n  13,\n  14,\n  15,\n  16,\n  17,\n  18,\n  19,\n  20,\n  21,\n  22,\n  23,\n  24,\n  25,\n  26,\n  27,\n  28,\n  29,\n  30,\n  31,\n  32,\n  33,\n  34,\n  35,\n  36,\n  37,\n  38,\n  39,\n  40,\n  41,\n  42,\n  43,\n  44,\n  45,\n  46,\n  47,\n  48,\n  49,\n  ...0[]\n]\n\n// Collects the results array into separate tuple array.\n//\n// T         - The array of the results\n// Collected - The collected tuples.\n// Depth     - The maximum depth.\ntype CollectResults<T, Collected extends unknown[] = [], Depth extends number = 50> = [\n  Depth,\n] extends [never]\n  ? []\n  : T extends [infer H, ...infer Rest]\n  ? // And test whether the head of the list is a result\n    H extends Result<infer L, infer R>\n    ? // Continue collecting...\n      CollectResults<\n        // the rest of the elements\n        Rest,\n        // The collected\n        [...Collected, [L, R]],\n        // and one less of the current depth\n        Prev[Depth]\n      >\n    : never // Impossible\n  : Collected\n\n// Transposes an array\n//\n// A          - The array source\n// Transposed - The collected transposed array\n// Depth      - The maximum depth.\nexport type Transpose<\n  A,\n  Transposed extends unknown[][] = [],\n  Depth extends number = 10\n> = A extends [infer T, ...infer Rest]\n  ? T extends [infer L, infer R]\n    ? Transposed extends [infer PL, infer PR]\n      ? PL extends unknown[]\n        ? PR extends unknown[]\n          ? Transpose<Rest, [[...PL, L], [...PR, R]], Prev[Depth]>\n          : never\n        : never\n      : Transpose<Rest, [[L], [R]], Prev[Depth]>\n    : Transposed\n  : Transposed\n\n// Combines the both sides of the array of the results into a tuple of the\n// union of the ok types and the union of the err types.\n//\n// T     - The array of the results\n// Depth - The maximum depth.\nexport type Combine<T, Depth extends number = 5> = Transpose<CollectResults<T>, [], Depth> extends [\n  infer L,\n  infer R,\n]\n  ? [UnknownMembersToNever<L>, UnknownMembersToNever<R>]\n  : Transpose<CollectResults<T>, [], Depth> extends []\n  ? [[], []]\n  : never\n\n// Deduplicates the result, as the result type is a union of Err and Ok types.\nexport type Dedup<T> = T extends Result<infer RL, infer RR>\n  ? [unknown] extends [RL]\n    ? Err<RL, RR>\n    : Ok<RL, RR>\n  : T\n\n// Given a union, this gives the array of the union members.\nexport type MemberListOf<T> = (\n  (T extends unknown ? (t: T) => T : never) extends infer U\n    ? (U extends unknown ? (u: U) => unknown : never) extends (v: infer V) => unknown\n      ? V\n      : never\n    : never\n) extends (_: unknown) => infer W\n  ? [...MemberListOf<Exclude<T, W>>, W]\n  : []\n\n// Converts an empty array to never.\n//\n// The second type parameter here will affect how to behave to `never[]`s.\n// If a precise type is required, pass `1` here so that it will resolve\n// a literal array such as `[ never, never ]`. Otherwise, set `0` or the default\n// type value will cause this to resolve the arrays containing only `never`\n// items as `never` only.\nexport type EmptyArrayToNever<T, NeverArrayToNever extends number = 0> = T extends []\n  ? never\n  : NeverArrayToNever extends 1\n  ? T extends [never, ...infer Rest]\n    ? [EmptyArrayToNever<Rest>] extends [never]\n      ? never\n      : T\n    : T\n  : T\n\n// Converts the `unknown` items of an array to `never`s.\ntype UnknownMembersToNever<T> = T extends [infer H, ...infer R]\n  ? [[unknown] extends [H] ? never : H, ...UnknownMembersToNever<R>]\n  : T\n\n// Gets the member type of the array or never.\nexport type MembersToUnion<T> = T extends unknown[] ? T[number] : never\n\n// Checks if the given type is a literal array.\nexport type IsLiteralArray<T> = T extends { length: infer L }\n  ? L extends number\n    ? number extends L\n      ? 0\n      : 1\n    : 0\n  : 0\n\n// Traverses an array of results and returns a single result containing\n// the oks and errs union-ed/combined.\ntype Traverse<T, Depth extends number = 5> = Combine<T, Depth> extends [infer Oks, infer Errs]\n  ? Result<EmptyArrayToNever<Oks, 1>, MembersToUnion<Errs>>\n  : never\n\n// Traverses an array of results and returns a single result containing\n// the oks combined and the array of errors combined.\ntype TraverseWithAllErrors<T, Depth extends number = 5> = Traverse<T, Depth> extends Result<\n  infer Oks,\n  infer Errs\n>\n  ? Result<Oks, Errs[]>\n  : never\n\n// Combines the array of results into one result.\nexport type CombineResults<\n  T extends readonly Result<unknown, unknown>[]\n> = IsLiteralArray<T> extends 1\n  ? Traverse<T>\n  : Result<ExtractOkTypes<T>, ExtractErrTypes<T>[number]>\n\n// Combines the array of results into one result with all errors.\nexport type CombineResultsWithAllErrorsArray<\n  T extends readonly Result<unknown, unknown>[]\n> = IsLiteralArray<T> extends 1\n  ? TraverseWithAllErrors<T>\n  : Result<ExtractOkTypes<T>, ExtractErrTypes<T>[number][]>\n\n//#endregion\n"
  },
  {
    "path": "tests/index.test.ts",
    "content": "import * as td from 'testdouble'\n\nimport {\n  err,\n  Err,\n  errAsync,\n  fromAsyncThrowable,\n  fromPromise,\n  fromSafePromise,\n  fromThrowable,\n  ok,\n  Ok,\n  okAsync,\n  Result,\n  ResultAsync,\n} from '../src'\n\nimport { vitest, describe, expect, it } from 'vitest'\n\ndescribe('Result.Ok', () => {\n  it('Creates an Ok value', () => {\n    const okVal = ok(12)\n\n    expect(okVal.isOk()).toBe(true)\n    expect(okVal.isErr()).toBe(false)\n    expect(okVal).toBeInstanceOf(Ok)\n  })\n\n  it('Creates an Ok value with null', () => {\n    const okVal = ok(null)\n\n    expect(okVal.isOk()).toBe(true)\n    expect(okVal.isErr()).toBe(false)\n    expect(okVal._unsafeUnwrap()).toBe(null)\n  })\n\n  it('Creates an Ok value with undefined', () => {\n    const okVal = ok(undefined)\n\n    expect(okVal.isOk()).toBe(true)\n    expect(okVal.isErr()).toBe(false)\n    expect(okVal._unsafeUnwrap()).toBeUndefined()\n  })\n\n  it('Is comparable', () => {\n    expect(ok(42)).toEqual(ok(42))\n    expect(ok(42)).not.toEqual(ok(43))\n  })\n\n  it('Maps over an Ok value', () => {\n    const okVal = ok(12)\n    const mapFn = vitest.fn((number) => number.toString())\n\n    const mapped = okVal.map(mapFn)\n\n    expect(mapped.isOk()).toBe(true)\n    expect(mapped._unsafeUnwrap()).toBe('12')\n    expect(mapFn).toHaveBeenCalledTimes(1)\n  })\n\n  it('Skips `mapErr`', () => {\n    const mapErrorFunc = vitest.fn((_error) => 'mapped error value')\n\n    const notMapped = ok(12).mapErr(mapErrorFunc)\n\n    expect(notMapped.isOk()).toBe(true)\n    expect(mapErrorFunc).not.toHaveBeenCalledTimes(1)\n  })\n\n  describe('andThen', () => {\n    it('Maps to an Ok', () => {\n      const okVal = ok(12)\n\n      const flattened = okVal.andThen((_number) => {\n        // ...\n        // complex logic\n        // ...\n        return ok({ data: 'why not' })\n      })\n\n      expect(flattened.isOk()).toBe(true)\n      expect(flattened._unsafeUnwrap()).toStrictEqual({ data: 'why not' })\n    })\n\n    it('Maps to an Err', () => {\n      const okval = ok(12)\n\n      const flattened = okval.andThen((_number) => {\n        // ...\n        // complex logic\n        // ...\n        return err('Whoopsies!')\n      })\n\n      expect(flattened.isOk()).toBe(false)\n\n      const nextFn = vitest.fn((_val) => ok('noop'))\n\n      flattened.andThen(nextFn)\n\n      expect(nextFn).not.toHaveBeenCalled()\n    })\n  })\n\n  describe('andThrough', () => {\n    it('Calls the passed function but returns an original ok', () => {\n      const okVal = ok(12)\n      const passedFn = vitest.fn((_number) => ok(undefined))\n\n      const thrued = okVal.andThrough(passedFn)\n      expect(thrued.isOk()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(thrued._unsafeUnwrap()).toStrictEqual(12)\n    })\n\n    it('Maps to an Err', () => {\n      const okval = ok(12)\n\n      const thrued = okval.andThen((_number) => {\n        // ...\n        // complex logic\n        // ...\n        return err('Whoopsies!')\n      })\n\n      expect(thrued.isOk()).toBe(false)\n      expect(thrued._unsafeUnwrapErr()).toStrictEqual('Whoopsies!')\n\n      const nextFn = vitest.fn((_val) => ok('noop'))\n\n      thrued.andThen(nextFn)\n\n      expect(nextFn).not.toHaveBeenCalled()\n    })\n  })\n\n  describe('andTee', () => {\n    it('Calls the passed function but returns an original ok', () => {\n      const okVal = ok(12)\n      const passedFn = vitest.fn((_number) => {})\n\n      const teed = okVal.andTee(passedFn)\n\n      expect(teed.isOk()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(teed._unsafeUnwrap()).toStrictEqual(12)\n    })\n    it('returns an original ok even when the passed function fails', () => {\n      const okVal = ok(12)\n      const passedFn = vitest.fn((_number) => {\n        throw new Error('OMG!')\n      })\n\n      const teed = okVal.andTee(passedFn)\n\n      expect(teed.isOk()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(teed._unsafeUnwrap()).toStrictEqual(12)\n    })\n  })\n\n  describe('orTee', () => {\n    it('Calls the passed function but returns an original err', () => {\n      const errVal = err(12)\n      const passedFn = vitest.fn((_number) => {})\n\n      const teed = errVal.orTee(passedFn)\n\n      expect(teed.isErr()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(teed._unsafeUnwrapErr()).toStrictEqual(12)\n    })\n    it('returns an original err even when the passed function fails', () => {\n      const errVal = err(12)\n      const passedFn = vitest.fn((_number) => {\n        throw new Error('OMG!')\n      })\n\n      const teed = errVal.orTee(passedFn)\n\n      expect(teed.isErr()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(teed._unsafeUnwrapErr()).toStrictEqual(12)\n    })\n  })\n\n  describe('asyncAndThrough', () => {\n    it('Calls the passed function but returns an original ok as Async', async () => {\n      const okVal = ok(12)\n      const passedFn = vitest.fn((_number) => okAsync(undefined))\n\n      const teedAsync = okVal.asyncAndThrough(passedFn)\n      expect(teedAsync).toBeInstanceOf(ResultAsync)\n      const teed = await teedAsync\n      expect(teed.isOk()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(teed._unsafeUnwrap()).toStrictEqual(12)\n    })\n\n    it('Maps to an Err', async () => {\n      const okval = ok(12)\n\n      const teedAsync = okval.asyncAndThen((_number) => {\n        // ...\n        // complex logic\n        // ...\n        return errAsync('Whoopsies!')\n      })\n      expect(teedAsync).toBeInstanceOf(ResultAsync)\n      const teed = await teedAsync\n      expect(teed.isOk()).toBe(false)\n      expect(teed._unsafeUnwrapErr()).toStrictEqual('Whoopsies!')\n\n      const nextFn = vitest.fn((_val) => ok('noop'))\n\n      teed.andThen(nextFn)\n\n      expect(nextFn).not.toHaveBeenCalled()\n    })\n  })\n  describe('orElse', () => {\n    it('Skips orElse on an Ok value', () => {\n      const okVal = ok(12)\n      const errorCallback = vitest.fn((_errVal) => err<number, string>('It is now a string'))\n\n      expect(okVal.orElse(errorCallback)).toEqual(ok(12))\n      expect(errorCallback).not.toHaveBeenCalled()\n    })\n  })\n\n  it('unwrapOr and return the Ok value', () => {\n    const okVal = ok(12)\n    expect(okVal.unwrapOr(1)).toEqual(12)\n  })\n\n  it('Maps to a ResultAsync', async () => {\n    const okVal = ok(12)\n\n    const flattened = okVal.asyncAndThen((_number) => {\n      // ...\n      // complex async logic\n      // ...\n      return okAsync({ data: 'why not' })\n    })\n\n    expect(flattened).toBeInstanceOf(ResultAsync)\n\n    const newResult = await flattened\n\n    expect(newResult.isOk()).toBe(true)\n    expect(newResult._unsafeUnwrap()).toStrictEqual({ data: 'why not' })\n  })\n\n  it('Maps to a promise', async () => {\n    const asyncMapper = vitest.fn((_val) => {\n      // ...\n      // complex logic\n      // ..\n\n      // db queries\n      // network calls\n      // disk io\n      // etc ...\n      return Promise.resolve('Very Nice!')\n    })\n\n    const okVal = ok(12)\n\n    const promise = okVal.asyncMap(asyncMapper)\n\n    expect(promise).toBeInstanceOf(ResultAsync)\n\n    const newResult = await promise\n\n    expect(newResult.isOk()).toBe(true)\n    expect(asyncMapper).toHaveBeenCalledTimes(1)\n    expect(newResult._unsafeUnwrap()).toStrictEqual('Very Nice!')\n  })\n\n  it('Matches on an Ok', () => {\n    const okMapper = vitest.fn((_val) => 'weeeeee')\n    const errMapper = vitest.fn((_val) => 'wooooo')\n\n    const matched = ok(12).match(okMapper, errMapper)\n\n    expect(matched).toBe('weeeeee')\n    expect(okMapper).toHaveBeenCalledTimes(1)\n    expect(errMapper).not.toHaveBeenCalled()\n  })\n\n  it('Unwraps without issue', () => {\n    const okVal = ok(12)\n\n    expect(okVal._unsafeUnwrap()).toBe(12)\n  })\n\n  it('Can read the value after narrowing', () => {\n    const fallible: () => Result<string, number> = () => ok('safe to read')\n    const val = fallible()\n\n    // After this check we val is narrowed to Ok<string, number>. Without this\n    // line TypeScript will not allow accessing val.value.\n    if (val.isErr()) return\n\n    expect(val.value).toBe('safe to read')\n  })\n})\n\ndescribe('Result.Err', () => {\n  it('Creates an Err value', () => {\n    const errVal = err('I have you now.')\n\n    expect(errVal.isOk()).toBe(false)\n    expect(errVal.isErr()).toBe(true)\n    expect(errVal).toBeInstanceOf(Err)\n  })\n\n  it('Is comparable', () => {\n    expect(err(42)).toEqual(err(42))\n    expect(err(42)).not.toEqual(err(43))\n  })\n\n  it('Skips `map`', () => {\n    const errVal = err('I am your father')\n\n    const mapper = vitest.fn((_value) => 'noooo')\n\n    const hopefullyNotMapped = errVal.map(mapper)\n\n    expect(hopefullyNotMapped.isErr()).toBe(true)\n    expect(mapper).not.toHaveBeenCalled()\n    expect(hopefullyNotMapped._unsafeUnwrapErr()).toEqual(errVal._unsafeUnwrapErr())\n  })\n\n  it('Maps over an Err', () => {\n    const errVal = err('Round 1, Fight!')\n\n    const mapper = vitest.fn((error: string) => error.replace('1', '2'))\n\n    const mapped = errVal.mapErr(mapper)\n\n    expect(mapped.isErr()).toBe(true)\n    expect(mapper).toHaveBeenCalledTimes(1)\n    expect(mapped._unsafeUnwrapErr()).not.toEqual(errVal._unsafeUnwrapErr())\n  })\n\n  it('unwrapOr and return the default value', () => {\n    const okVal = err<number, string>('Oh nooo')\n    expect(okVal.unwrapOr(1)).toEqual(1)\n  })\n\n  it('Skips over andThen', () => {\n    const errVal = err('Yolo')\n\n    const mapper = vitest.fn((_val) => ok<string, string>('yooyo'))\n\n    const hopefullyNotFlattened = errVal.andThen(mapper)\n\n    expect(hopefullyNotFlattened.isErr()).toBe(true)\n    expect(mapper).not.toHaveBeenCalled()\n    expect(errVal._unsafeUnwrapErr()).toEqual('Yolo')\n  })\n\n  it('Skips over andThrough', () => {\n    const errVal = err('Yolo')\n\n    const mapper = vitest.fn((_val) => ok<void, string>(undefined))\n\n    const hopefullyNotFlattened = errVal.andThrough(mapper)\n\n    expect(hopefullyNotFlattened.isErr()).toBe(true)\n    expect(mapper).not.toHaveBeenCalled()\n    expect(errVal._unsafeUnwrapErr()).toEqual('Yolo')\n  })\n\n  it('Skips over andTee', () => {\n    const errVal = err('Yolo')\n\n    const mapper = vitest.fn((_val) => {})\n\n    const hopefullyNotFlattened = errVal.andTee(mapper)\n\n    expect(hopefullyNotFlattened.isErr()).toBe(true)\n    expect(mapper).not.toHaveBeenCalled()\n    expect(errVal._unsafeUnwrapErr()).toEqual('Yolo')\n  })\n\n  it('Skips over asyncAndThrough but returns ResultAsync instead', async () => {\n    const errVal = err('Yolo')\n\n    const mapper = vitest.fn((_val) => okAsync<string, unknown>('Async'))\n\n    const hopefullyNotFlattened = errVal.asyncAndThrough(mapper)\n    expect(hopefullyNotFlattened).toBeInstanceOf(ResultAsync)\n\n    const result = await hopefullyNotFlattened\n    expect(result.isErr()).toBe(true)\n    expect(mapper).not.toHaveBeenCalled()\n    expect(result._unsafeUnwrapErr()).toEqual('Yolo')\n  })\n\n  it('Transforms error into ResultAsync within `asyncAndThen`', async () => {\n    const errVal = err('Yolo')\n\n    const asyncMapper = vitest.fn((_val) => okAsync<string, string>('yooyo'))\n\n    const hopefullyNotFlattened = errVal.asyncAndThen(asyncMapper)\n\n    expect(hopefullyNotFlattened).toBeInstanceOf(ResultAsync)\n    expect(asyncMapper).not.toHaveBeenCalled()\n\n    const syncResult = await hopefullyNotFlattened\n    expect(syncResult._unsafeUnwrapErr()).toEqual('Yolo')\n  })\n\n  it('Does not invoke callback within `asyncMap`', async () => {\n    const asyncMapper = vitest.fn((_val) => {\n      // ...\n      // complex logic\n      // ..\n\n      // db queries\n      // network calls\n      // disk io\n      // etc ...\n      return Promise.resolve('Very Nice!')\n    })\n\n    const errVal = err('nooooooo')\n\n    const promise = errVal.asyncMap(asyncMapper)\n\n    expect(promise).toBeInstanceOf(ResultAsync)\n\n    const sameResult = await promise\n\n    expect(sameResult.isErr()).toBe(true)\n    expect(asyncMapper).not.toHaveBeenCalled()\n    expect(sameResult._unsafeUnwrapErr()).toEqual(errVal._unsafeUnwrapErr())\n  })\n\n  it('Matches on an Err', () => {\n    const okMapper = vitest.fn((_val) => 'weeeeee')\n    const errMapper = vitest.fn((_val) => 'wooooo')\n\n    const matched = err(12).match(okMapper, errMapper)\n\n    expect(matched).toBe('wooooo')\n    expect(okMapper).not.toHaveBeenCalled()\n    expect(errMapper).toHaveBeenCalledTimes(1)\n  })\n\n  it('Throws when you unwrap an Err', () => {\n    const errVal = err('woopsies')\n\n    expect(() => {\n      errVal._unsafeUnwrap()\n    }).toThrowError()\n  })\n\n  it('Unwraps without issue', () => {\n    const okVal = err(12)\n\n    expect(okVal._unsafeUnwrapErr()).toBe(12)\n  })\n\n  describe('orElse', () => {\n    it('invokes the orElse callback on an Err value', () => {\n      const okVal = err('BOOOM!')\n      const errorCallback = vitest.fn((_errVal) => err(true))\n\n      expect(okVal.orElse(errorCallback)).toEqual(err(true))\n      expect(errorCallback).toHaveBeenCalledTimes(1)\n    })\n  })\n})\n\ndescribe('Result.fromThrowable', () => {\n  it('Creates a function that returns an OK result when the inner function does not throw', () => {\n    const hello = (): string => 'hello'\n    const safeHello = Result.fromThrowable(hello)\n\n    const result = hello()\n    const safeResult = safeHello()\n\n    expect(safeResult).toBeInstanceOf(Ok)\n    expect(result).toEqual(safeResult._unsafeUnwrap())\n  })\n\n  // Added for issue #300 -- the test here is not so much that expectations are met as that the test compiles.\n  it('Accepts an inner function which takes arguments', () => {\n    const hello = (fname: string): string => `hello, ${fname}`\n    const safeHello = Result.fromThrowable(hello)\n\n    const result = hello('Dikembe')\n    const safeResult = safeHello('Dikembe')\n\n    expect(safeResult).toBeInstanceOf(Ok)\n    expect(result).toEqual(safeResult._unsafeUnwrap())\n  })\n\n  it('Creates a function that returns an err when the inner function throws', () => {\n    const thrower = (): string => {\n      throw new Error()\n    }\n\n    // type: () => Result<string, unknown>\n    // received types from thrower fn, no errorFn is provides therefore Err type is unknown\n    const safeThrower = Result.fromThrowable(thrower)\n    const result = safeThrower()\n\n    expect(result).toBeInstanceOf(Err)\n    expect(result._unsafeUnwrapErr()).toBeInstanceOf(Error)\n  })\n\n  it('Accepts an error handler as a second argument', () => {\n    const thrower = (): string => {\n      throw new Error()\n    }\n    type MessageObject = { message: string }\n    const toMessageObject = (): MessageObject => ({ message: 'error' })\n\n    // type: () => Result<string, MessageObject>\n    // received types from thrower fn and errorFn return type\n    const safeThrower = Result.fromThrowable(thrower, toMessageObject)\n    const result = safeThrower()\n\n    expect(result.isOk()).toBe(false)\n    expect(result.isErr()).toBe(true)\n    expect(result).toBeInstanceOf(Err)\n    expect(result._unsafeUnwrapErr()).toEqual({ message: 'error' })\n  })\n\n  it('has a top level export', () => {\n    expect(fromThrowable).toBe(Result.fromThrowable)\n  })\n})\n\ndescribe('Utils', () => {\n  describe('`Result.combine`', () => {\n    describe('Synchronous `combine`', () => {\n      it('Combines a list of results into an Ok value', () => {\n        const resultList = [ok(123), ok(456), ok(789)]\n\n        const result = Result.combine(resultList)\n\n        expect(result.isOk()).toBe(true)\n        expect(result._unsafeUnwrap()).toEqual([123, 456, 789])\n      })\n\n      it('Combines a list of results into an Err value', () => {\n        const resultList: Result<number, string>[] = [\n          ok(123),\n          err('boooom!'),\n          ok(456),\n          err('ahhhhh!'),\n        ]\n\n        const result = Result.combine(resultList)\n\n        expect(result.isErr()).toBe(true)\n        expect(result._unsafeUnwrapErr()).toBe('boooom!')\n      })\n\n      it('Combines heterogeneous lists', () => {\n        type HeterogenousList = [\n          Result<string, string>,\n          Result<number, number>,\n          Result<boolean, boolean>,\n        ]\n\n        const heterogenousList: HeterogenousList = [ok('Yooooo'), ok(123), ok(true)]\n\n        type ExpecteResult = Result<[string, number, boolean], string | number | boolean>\n\n        const result: ExpecteResult = Result.combine(heterogenousList)\n\n        expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true])\n      })\n\n      it('Does not destructure / concatenate arrays', () => {\n        type HomogenousList = [Result<string[], boolean>, Result<number[], string>]\n\n        const homogenousList: HomogenousList = [ok(['hello', 'world']), ok([1, 2, 3])]\n\n        type ExpectedResult = Result<[string[], number[]], boolean | string>\n\n        const result: ExpectedResult = Result.combine(homogenousList)\n\n        expect(result._unsafeUnwrap()).toEqual([\n          ['hello', 'world'],\n          [1, 2, 3],\n        ])\n      })\n    })\n\n    describe('`ResultAsync.combine`', () => {\n      it('Combines a list of async results into an Ok value', async () => {\n        const asyncResultList = [okAsync(123), okAsync(456), okAsync(789)]\n\n        const resultAsync: ResultAsync<number[], never[]> = ResultAsync.combine(asyncResultList)\n\n        expect(resultAsync).toBeInstanceOf(ResultAsync)\n\n        const result = await ResultAsync.combine(asyncResultList)\n\n        expect(result.isOk()).toBe(true)\n        expect(result._unsafeUnwrap()).toEqual([123, 456, 789])\n      })\n\n      it('Combines a list of results into an Err value', async () => {\n        const resultList: ResultAsync<number, string>[] = [\n          okAsync(123),\n          errAsync('boooom!'),\n          okAsync(456),\n          errAsync('ahhhhh!'),\n        ]\n\n        const result = await ResultAsync.combine(resultList)\n\n        expect(result.isErr()).toBe(true)\n        expect(result._unsafeUnwrapErr()).toBe('boooom!')\n      })\n\n      it('Combines heterogeneous lists', async () => {\n        type HeterogenousList = [\n          ResultAsync<string, string>,\n          ResultAsync<number, number>,\n          ResultAsync<boolean, boolean>,\n          ResultAsync<number[], string>,\n        ]\n\n        const heterogenousList: HeterogenousList = [\n          okAsync('Yooooo'),\n          okAsync(123),\n          okAsync(true),\n          okAsync([1, 2, 3]),\n        ]\n\n        type ExpecteResult = Result<[string, number, boolean, number[]], string | number | boolean>\n\n        const result: ExpecteResult = await ResultAsync.combine(heterogenousList)\n\n        expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true, [1, 2, 3]])\n      })\n    })\n  })\n  describe('`Result.combineWithAllErrors`', () => {\n    describe('Synchronous `combineWithAllErrors`', () => {\n      it('Combines a list of results into an Ok value', () => {\n        const resultList = [ok(123), ok(456), ok(789)]\n\n        const result = Result.combineWithAllErrors(resultList)\n\n        expect(result.isOk()).toBe(true)\n        expect(result._unsafeUnwrap()).toEqual([123, 456, 789])\n      })\n\n      it('Combines a list of results into an Err value', () => {\n        const resultList: Result<number, string>[] = [\n          ok(123),\n          err('boooom!'),\n          ok(456),\n          err('ahhhhh!'),\n        ]\n\n        const result = Result.combineWithAllErrors(resultList)\n\n        expect(result.isErr()).toBe(true)\n        expect(result._unsafeUnwrapErr()).toEqual(['boooom!', 'ahhhhh!'])\n      })\n\n      it('Combines heterogeneous lists', () => {\n        type HeterogenousList = [\n          Result<string, string>,\n          Result<number, number>,\n          Result<boolean, boolean>,\n        ]\n\n        const heterogenousList: HeterogenousList = [ok('Yooooo'), ok(123), ok(true)]\n\n        type ExpecteResult = Result<[string, number, boolean], (string | number | boolean)[]>\n\n        const result: ExpecteResult = Result.combineWithAllErrors(heterogenousList)\n\n        expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true])\n      })\n\n      it('Does not destructure / concatenate arrays', () => {\n        type HomogenousList = [Result<string[], boolean>, Result<number[], string>]\n\n        const homogenousList: HomogenousList = [ok(['hello', 'world']), ok([1, 2, 3])]\n\n        type ExpectedResult = Result<[string[], number[]], (boolean | string)[]>\n\n        const result: ExpectedResult = Result.combineWithAllErrors(homogenousList)\n\n        expect(result._unsafeUnwrap()).toEqual([\n          ['hello', 'world'],\n          [1, 2, 3],\n        ])\n      })\n    })\n    describe('`ResultAsync.combineWithAllErrors`', () => {\n      it('Combines a list of async results into an Ok value', async () => {\n        const asyncResultList = [okAsync(123), okAsync(456), okAsync(789)]\n\n        const result = await ResultAsync.combineWithAllErrors(asyncResultList)\n\n        expect(result.isOk()).toBe(true)\n        expect(result._unsafeUnwrap()).toEqual([123, 456, 789])\n      })\n\n      it('Combines a list of results into an Err value', async () => {\n        const asyncResultList: ResultAsync<number, string>[] = [\n          okAsync(123),\n          errAsync('boooom!'),\n          okAsync(456),\n          errAsync('ahhhhh!'),\n        ]\n\n        const result = await ResultAsync.combineWithAllErrors(asyncResultList)\n\n        expect(result.isErr()).toBe(true)\n        expect(result._unsafeUnwrapErr()).toEqual(['boooom!', 'ahhhhh!'])\n      })\n\n      it('Combines heterogeneous lists', async () => {\n        type HeterogenousList = [\n          ResultAsync<string, string>,\n          ResultAsync<number, number>,\n          ResultAsync<boolean, boolean>,\n        ]\n\n        const heterogenousList: HeterogenousList = [okAsync('Yooooo'), okAsync(123), okAsync(true)]\n\n        type ExpecteResult = Result<[string, number, boolean], (string | number | boolean)[]>\n\n        const result: ExpecteResult = await ResultAsync.combineWithAllErrors(heterogenousList)\n\n        expect(result._unsafeUnwrap()).toEqual(['Yooooo', 123, true])\n      })\n    })\n\n    describe('testdouble `ResultAsync.combine`', () => {\n      interface ITestInterface {\n        getName(): string\n        setName(name: string): void\n        getAsyncResult(): ResultAsync<ITestInterface, Error>\n      }\n\n      it('Combines `testdouble` proxies from mocks generated via interfaces', async () => {\n        const mock = td.object<ITestInterface>()\n\n        const result = await ResultAsync.combine([okAsync(mock)] as const)\n\n        expect(result).toBeDefined()\n        expect(result.isErr()).toBeFalsy()\n        const unwrappedResult = result._unsafeUnwrap()\n\n        expect(unwrappedResult.length).toBe(1)\n        expect(unwrappedResult[0]).toBe(mock)\n      })\n    })\n  })\n})\n\ndescribe('ResultAsync', () => {\n  it('Is awaitable to a Result', async () => {\n    // For a success value\n    const asyncVal = okAsync(12)\n    expect(asyncVal).toBeInstanceOf(ResultAsync)\n\n    const val = await asyncVal\n\n    expect(val).toBeInstanceOf(Ok)\n    expect(val._unsafeUnwrap()).toEqual(12)\n\n    // For an error\n    const asyncErr = errAsync('Wrong format')\n    expect(asyncErr).toBeInstanceOf(ResultAsync)\n\n    const err = await asyncErr\n\n    expect(err).toBeInstanceOf(Err)\n    expect(err._unsafeUnwrapErr()).toEqual('Wrong format')\n  })\n\n  describe('acting as a Promise<Result>', () => {\n    it('Is chainable like any Promise', async () => {\n      // For a success value\n      const asyncValChained = okAsync(12).then((res) => {\n        if (res.isOk()) {\n          return res.value + 2\n        }\n      })\n\n      expect(asyncValChained).toBeInstanceOf(Promise)\n      const val = await asyncValChained\n      expect(val).toEqual(14)\n\n      // For an error\n      const asyncErrChained = errAsync('Oops').then((res) => {\n        if (res.isErr()) {\n          return res.error + '!'\n        }\n      })\n\n      expect(asyncErrChained).toBeInstanceOf(Promise)\n      const err = await asyncErrChained\n      expect(err).toEqual('Oops!')\n    })\n\n    it('Can be used with Promise.all', async () => {\n      const allResult = await Promise.all([okAsync<string, Error>('1')])\n\n      expect(allResult).toHaveLength(1)\n      expect(allResult[0]).toBeInstanceOf(Ok)\n      if (!(allResult[0] instanceof Ok)) return\n      expect(allResult[0].isOk()).toBe(true)\n      expect(allResult[0]._unsafeUnwrap()).toEqual('1')\n    })\n\n    it('rejects if the underlying promise is rejected', () => {\n      const asyncResult = new ResultAsync(Promise.reject('oops'))\n      expect(asyncResult).rejects.toBe('oops')\n    })\n  })\n\n  describe('map', () => {\n    it('Maps a value using a synchronous function', async () => {\n      const asyncVal = okAsync(12)\n\n      const mapSyncFn = vitest.fn((number) => number.toString())\n\n      const mapped = asyncVal.map(mapSyncFn)\n\n      expect(mapped).toBeInstanceOf(ResultAsync)\n\n      const newVal = await mapped\n\n      expect(newVal.isOk()).toBe(true)\n      expect(newVal._unsafeUnwrap()).toBe('12')\n      expect(mapSyncFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Maps a value using an asynchronous function', async () => {\n      const asyncVal = okAsync(12)\n\n      const mapAsyncFn = vitest.fn((number) => Promise.resolve(number.toString()))\n\n      const mapped = asyncVal.map(mapAsyncFn)\n\n      expect(mapped).toBeInstanceOf(ResultAsync)\n\n      const newVal = await mapped\n\n      expect(newVal.isOk()).toBe(true)\n      expect(newVal._unsafeUnwrap()).toBe('12')\n      expect(mapAsyncFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Skips an error', async () => {\n      const asyncErr = errAsync<number, string>('Wrong format')\n\n      const mapSyncFn = vitest.fn((number) => number.toString())\n\n      const notMapped = asyncErr.map(mapSyncFn)\n\n      expect(notMapped).toBeInstanceOf(ResultAsync)\n\n      const newVal = await notMapped\n\n      expect(newVal.isErr()).toBe(true)\n      expect(newVal._unsafeUnwrapErr()).toBe('Wrong format')\n      expect(mapSyncFn).toHaveBeenCalledTimes(0)\n    })\n  })\n\n  describe('mapErr', () => {\n    it('Maps an error using a synchronous function', async () => {\n      const asyncErr = errAsync('Wrong format')\n\n      const mapErrSyncFn = vitest.fn((str) => 'Error: ' + str)\n\n      const mappedErr = asyncErr.mapErr(mapErrSyncFn)\n\n      expect(mappedErr).toBeInstanceOf(ResultAsync)\n\n      const newVal = await mappedErr\n\n      expect(newVal.isErr()).toBe(true)\n      expect(newVal._unsafeUnwrapErr()).toBe('Error: Wrong format')\n      expect(mapErrSyncFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Maps an error using an asynchronous function', async () => {\n      const asyncErr = errAsync('Wrong format')\n\n      const mapErrAsyncFn = vitest.fn((str) => Promise.resolve('Error: ' + str))\n\n      const mappedErr = asyncErr.mapErr(mapErrAsyncFn)\n\n      expect(mappedErr).toBeInstanceOf(ResultAsync)\n\n      const newVal = await mappedErr\n\n      expect(newVal.isErr()).toBe(true)\n      expect(newVal._unsafeUnwrapErr()).toBe('Error: Wrong format')\n      expect(mapErrAsyncFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Skips a value', async () => {\n      const asyncVal = okAsync(12)\n\n      const mapErrSyncFn = vitest.fn((str) => 'Error: ' + str)\n\n      const notMapped = asyncVal.mapErr(mapErrSyncFn)\n\n      expect(notMapped).toBeInstanceOf(ResultAsync)\n\n      const newVal = await notMapped\n\n      expect(newVal.isOk()).toBe(true)\n      expect(newVal._unsafeUnwrap()).toBe(12)\n      expect(mapErrSyncFn).toHaveBeenCalledTimes(0)\n    })\n  })\n\n  describe('andThen', () => {\n    it('Maps a value using a function returning a ResultAsync', async () => {\n      const asyncVal = okAsync(12)\n\n      const andThenResultAsyncFn = vitest.fn(() => okAsync('good'))\n\n      const mapped = asyncVal.andThen(andThenResultAsyncFn)\n\n      expect(mapped).toBeInstanceOf(ResultAsync)\n\n      const newVal = await mapped\n\n      expect(newVal.isOk()).toBe(true)\n      expect(newVal._unsafeUnwrap()).toBe('good')\n      expect(andThenResultAsyncFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Maps a value using a function returning a Result', async () => {\n      const asyncVal = okAsync(12)\n\n      const andThenResultFn = vitest.fn(() => ok('good'))\n\n      const mapped = asyncVal.andThen(andThenResultFn)\n\n      expect(mapped).toBeInstanceOf(ResultAsync)\n\n      const newVal = await mapped\n\n      expect(newVal.isOk()).toBe(true)\n      expect(newVal._unsafeUnwrap()).toBe('good')\n      expect(andThenResultFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Skips an Error', async () => {\n      const asyncVal = errAsync<string, string>('Wrong format')\n\n      const andThenResultFn = vitest.fn(() => ok<string, string>('good'))\n\n      const notMapped = asyncVal.andThen(andThenResultFn)\n\n      expect(notMapped).toBeInstanceOf(ResultAsync)\n\n      const newVal = await notMapped\n\n      expect(newVal.isErr()).toBe(true)\n      expect(newVal._unsafeUnwrapErr()).toBe('Wrong format')\n      expect(andThenResultFn).toHaveBeenCalledTimes(0)\n    })\n  })\n\n  describe('andThrough', () => {\n    it('Returns the original value when map function returning ResultAsync succeeds', async () => {\n      const asyncVal = okAsync(12)\n      /*\n        A couple examples of this function\n\n        DB persistence (create or update)\n        API calls (create or update)\n      */\n      const andThroughResultAsyncFn = vitest.fn(() => okAsync('good'))\n\n      const thrued = asyncVal.andThrough(andThroughResultAsyncFn)\n\n      expect(thrued).toBeInstanceOf(ResultAsync)\n\n      const result = await thrued\n\n      expect(result.isOk()).toBe(true)\n      expect(result._unsafeUnwrap()).toBe(12)\n      expect(andThroughResultAsyncFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Maps to an error when map function returning ResultAsync fails', async () => {\n      const asyncVal = okAsync(12)\n\n      const andThroughResultAsyncFn = vitest.fn(() => errAsync('oh no!'))\n\n      const thrued = asyncVal.andThrough(andThroughResultAsyncFn)\n\n      expect(thrued).toBeInstanceOf(ResultAsync)\n\n      const result = await thrued\n\n      expect(result.isErr()).toBe(true)\n      expect(result._unsafeUnwrapErr()).toBe('oh no!')\n      expect(andThroughResultAsyncFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Returns the original value when map function returning Result succeeds', async () => {\n      const asyncVal = okAsync(12)\n\n      const andThroughResultFn = vitest.fn(() => ok('good'))\n\n      const thrued = asyncVal.andThrough(andThroughResultFn)\n\n      expect(thrued).toBeInstanceOf(ResultAsync)\n\n      const newVal = await thrued\n\n      expect(newVal.isOk()).toBe(true)\n      expect(newVal._unsafeUnwrap()).toBe(12)\n      expect(andThroughResultFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Maps to an error when map function returning Result fails', async () => {\n      const asyncVal = okAsync(12)\n\n      const andThroughResultFn = vitest.fn(() => err('oh no!'))\n\n      const thrued = asyncVal.andThrough(andThroughResultFn)\n\n      expect(thrued).toBeInstanceOf(ResultAsync)\n\n      const newVal = await thrued\n\n      expect(newVal.isErr()).toBe(true)\n      expect(newVal._unsafeUnwrapErr()).toBe('oh no!')\n      expect(andThroughResultFn).toHaveBeenCalledTimes(1)\n    })\n\n    it('Skips an Error', async () => {\n      const asyncVal = errAsync<string, string>('Wrong format')\n\n      const andThroughResultFn = vitest.fn(() => ok<string, string>('good'))\n\n      const notMapped = asyncVal.andThrough(andThroughResultFn)\n\n      expect(notMapped).toBeInstanceOf(ResultAsync)\n\n      const newVal = await notMapped\n\n      expect(newVal.isErr()).toBe(true)\n      expect(newVal._unsafeUnwrapErr()).toBe('Wrong format')\n      expect(andThroughResultFn).toHaveBeenCalledTimes(0)\n    })\n  })\n\n  describe('andTee', () => {\n    it('Calls the passed function but returns an original ok', async () => {\n      const okVal = okAsync(12)\n      const passedFn = vitest.fn((_number) => {})\n\n      const teed = await okVal.andTee(passedFn)\n\n      expect(teed.isOk()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(teed._unsafeUnwrap()).toStrictEqual(12)\n    })\n    it('returns an original ok even when the passed function fails', async () => {\n      const okVal = okAsync(12)\n      const passedFn = vitest.fn((_number) => {\n        throw new Error('OMG!')\n      })\n\n      const teed = await okVal.andTee(passedFn)\n\n      expect(teed.isOk()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(teed._unsafeUnwrap()).toStrictEqual(12)\n    })\n  })\n\n  describe('orTee', () => {\n    it('Calls the passed function but returns an original err', async () => {\n      const errVal = errAsync(12)\n      const passedFn = vitest.fn((_number) => {})\n\n      const teed = await errVal.orTee(passedFn)\n\n      expect(teed.isErr()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(teed._unsafeUnwrapErr()).toStrictEqual(12)\n    })\n    it('returns an original err even when the passed function fails', async () => {\n      const errVal = errAsync(12)\n      const passedFn = vitest.fn((_number) => {\n        throw new Error('OMG!')\n      })\n\n      const teed = await errVal.orTee(passedFn)\n\n      expect(teed.isErr()).toBe(true)\n      expect(passedFn).toHaveBeenCalledTimes(1)\n      expect(teed._unsafeUnwrapErr()).toStrictEqual(12)\n    })\n  })\n\n  describe('orElse', () => {\n    it('Skips orElse on an Ok value', async () => {\n      const okVal = okAsync(12)\n      const errorCallback = vitest.fn((_errVal) => errAsync<number, string>('It is now a string'))\n\n      const result = await okVal.orElse(errorCallback)\n\n      expect(result).toEqual(ok(12))\n\n      expect(errorCallback).not.toHaveBeenCalled()\n    })\n\n    it('Invokes the orElse callback on an Err value', async () => {\n      const myResult = errAsync('BOOOM!')\n      const errorCallback = vitest.fn((_errVal) => errAsync(true))\n\n      const result = await myResult.orElse(errorCallback)\n\n      expect(result).toEqual(err(true))\n      expect(errorCallback).toHaveBeenCalledTimes(1)\n    })\n\n    it('Accepts a regular Result in the callback', async () => {\n      const myResult = errAsync('BOOOM!')\n      const errorCallback = vitest.fn((_errVal) => err(true))\n\n      const result = await myResult.orElse(errorCallback)\n\n      expect(result).toEqual(err(true))\n      expect(errorCallback).toHaveBeenCalledTimes(1)\n    })\n  })\n\n  describe('match', () => {\n    it('Matches on an Ok', async () => {\n      const okMapper = vitest.fn((_val) => 'weeeeee')\n      const errMapper = vitest.fn((_val) => 'wooooo')\n\n      const matched = await okAsync(12).match(okMapper, errMapper)\n\n      expect(matched).toBe('weeeeee')\n      expect(okMapper).toHaveBeenCalledTimes(1)\n      expect(errMapper).not.toHaveBeenCalled()\n    })\n\n    it('Matches on an Error', async () => {\n      const okMapper = vitest.fn((_val) => 'weeeeee')\n      const errMapper = vitest.fn((_val) => 'wooooo')\n\n      const matched = await errAsync('bad').match(okMapper, errMapper)\n\n      expect(matched).toBe('wooooo')\n      expect(okMapper).not.toHaveBeenCalled()\n      expect(errMapper).toHaveBeenCalledTimes(1)\n    })\n  })\n\n  describe('unwrapOr', () => {\n    it('returns a promise to the result value on an Ok', async () => {\n      const unwrapped = await okAsync(12).unwrapOr(10)\n      expect(unwrapped).toBe(12)\n    })\n\n    it('returns a promise to the provided default value on an Error', async () => {\n      const unwrapped = await errAsync<number, number>(12).unwrapOr(10)\n      expect(unwrapped).toBe(10)\n    })\n  })\n\n  describe('fromSafePromise', () => {\n    it('Creates a ResultAsync from a Promise', async () => {\n      const res = ResultAsync.fromSafePromise(Promise.resolve(12))\n\n      expect(res).toBeInstanceOf(ResultAsync)\n\n      const val = await res\n      expect(val.isOk()).toBe(true)\n      expect(val._unsafeUnwrap()).toEqual(12)\n    })\n\n    it('has a top level export', () => {\n      expect(fromSafePromise).toBe(ResultAsync.fromSafePromise)\n    })\n  })\n\n  describe('fromPromise', () => {\n    it('Accepts an error handler as a second argument', async () => {\n      const res = ResultAsync.fromPromise(Promise.reject('No!'), (e) => new Error('Oops: ' + e))\n\n      expect(res).toBeInstanceOf(ResultAsync)\n\n      const val = await res\n      expect(val.isErr()).toBe(true)\n      expect(val._unsafeUnwrapErr()).toEqual(Error('Oops: No!'))\n    })\n\n    it('has a top level export', () => {\n      expect(fromPromise).toBe(ResultAsync.fromPromise)\n    })\n  })\n\n  describe('ResultAsync.fromThrowable', () => {\n    it('creates a new function that returns a ResultAsync', async () => {\n      const example = ResultAsync.fromThrowable(async (a: number, b: number) => a + b)\n      const res = example(4, 8)\n      expect(res).toBeInstanceOf(ResultAsync)\n\n      const val = await res\n      expect(val.isOk()).toBe(true)\n      expect(val._unsafeUnwrap()).toEqual(12)\n    })\n\n    it('handles synchronous errors', async () => {\n      const example = ResultAsync.fromThrowable(() => {\n        if (1 > 0) throw new Error('Oops: No!')\n\n        return Promise.resolve(12)\n      })\n\n      const val = await example()\n      expect(val.isErr()).toBe(true)\n\n      expect(val._unsafeUnwrapErr()).toEqual(Error('Oops: No!'))\n    })\n\n    it('handles asynchronous errors', async () => {\n      const example = ResultAsync.fromThrowable(async () => {\n        if (1 > 0) throw new Error('Oops: No!')\n\n        return 12\n      })\n\n      const val = await example()\n      expect(val.isErr()).toBe(true)\n\n      expect(val._unsafeUnwrapErr()).toEqual(Error('Oops: No!'))\n    })\n\n    it('Accepts an error handler as a second argument', async () => {\n      const example = ResultAsync.fromThrowable(\n        () => Promise.reject('No!'),\n        (e) => new Error('Oops: ' + e),\n      )\n\n      const val = await example()\n      expect(val.isErr()).toBe(true)\n\n      expect(val._unsafeUnwrapErr()).toEqual(TypeError('Oops: No!'))\n    })\n\n    it('has a top level export', () => {\n      expect(fromAsyncThrowable).toBe(ResultAsync.fromThrowable)\n    })\n  })\n\n  describe('okAsync', () => {\n    it('Creates a ResultAsync that resolves to an Ok', async () => {\n      const val = okAsync(12)\n\n      expect(val).toBeInstanceOf(ResultAsync)\n\n      const res = await val\n\n      expect(res.isOk()).toBe(true)\n      expect(res._unsafeUnwrap()).toEqual(12)\n    })\n  })\n\n  describe('errAsync', () => {\n    it('Creates a ResultAsync that resolves to an Err', async () => {\n      const err = errAsync('bad')\n\n      expect(err).toBeInstanceOf(ResultAsync)\n\n      const res = await err\n\n      expect(res.isErr()).toBe(true)\n      expect(res._unsafeUnwrapErr()).toEqual('bad')\n    })\n  })\n})\n"
  },
  {
    "path": "tests/safe-try.test.ts",
    "content": "import {\n  safeTry,\n  ok,\n  okAsync,\n  err,\n  errAsync,\n  Ok,\n  Err,\n  Result,\n  ResultAsync,\n} from \"../src\"\n\nimport { describe, expect, test } from 'vitest'\n\ndescribe('Returns what is returned from the generator function', () => {\n  const val = \"value\"\n\n  test(\"With synchronous Ok\", () => {\n    const res = safeTry(function*() {\n      return ok(val)\n    })\n    expect(res).toBeInstanceOf(Ok)\n    expect(res._unsafeUnwrap()).toBe(val)\n  })\n\n  test(\"With synchronous Err\", () => {\n    const res = safeTry(function*() {\n      return err(val)\n    })\n    expect(res).toBeInstanceOf(Err)\n    expect(res._unsafeUnwrapErr()).toBe(val)\n  })\n\n  test(\"With async Ok\", async () => {\n    const res = await safeTry(async function*() {\n      return await okAsync(val)\n    })\n    expect(res).toBeInstanceOf(Ok)\n    expect(res._unsafeUnwrap()).toBe(val)\n  })\n\n  test(\"With async Err\", async () => {\n    const res = await safeTry(async function*() {\n      return await errAsync(val)\n    })\n    expect(res).toBeInstanceOf(Err)\n    expect(res._unsafeUnwrapErr()).toBe(val)\n  })\n})\n\ndescribe(\"Returns the first occurence of Err instance as yiled*'s operand\", () => {\n  test(\"With synchronous results\", () => {\n    const errVal = \"err\"\n    const okValues = Array<string>()\n\n    const result = safeTry(function*() {\n      const okFoo = yield* ok(\"foo\").safeUnwrap()\n      okValues.push(okFoo)\n\n      const okBar = yield* ok(\"bar\").safeUnwrap()\n      okValues.push(okBar)\n\n      yield* err(errVal).safeUnwrap()\n\n      throw new Error(\"This line should not be executed\")\n    })\n\n    expect(okValues).toMatchObject([\"foo\", \"bar\"])\n\n    expect(result).toBeInstanceOf(Err)\n    expect(result._unsafeUnwrapErr()).toBe(errVal)\n  })\n\n  test(\"With async results\", async () => {\n    const errVal = \"err\"\n    const okValues = Array<string>()\n\n    const result = await safeTry(async function*() {\n      const okFoo = yield* okAsync(\"foo\").safeUnwrap()\n      okValues.push(okFoo)\n\n      const okBar = yield* okAsync(\"bar\").safeUnwrap()\n      okValues.push(okBar)\n\n      yield* errAsync(errVal).safeUnwrap()\n\n      throw new Error(\"This line should not be executed\")\n    })\n\n    expect(okValues).toMatchObject([\"foo\", \"bar\"])\n\n    expect(result).toBeInstanceOf(Err)\n    expect(result._unsafeUnwrapErr()).toBe(errVal)\n  })\n\n  test(\"Mix results of synchronous and async in AsyncGenerator\", async () => {\n    const errVal = \"err\"\n    const okValues = Array<string>()\n\n    const result = await safeTry(async function*() {\n      const okFoo = yield* okAsync(\"foo\").safeUnwrap()\n      okValues.push(okFoo)\n\n      const okBar = yield* ok(\"bar\").safeUnwrap()\n      okValues.push(okBar)\n\n      yield* err(errVal).safeUnwrap()\n\n      throw new Error(\"This line should not be executed\")\n    })\n\n    expect(okValues).toMatchObject([\"foo\", \"bar\"])\n\n    expect(result).toBeInstanceOf(Err)\n    expect(result._unsafeUnwrapErr()).toBe(errVal)\n  })\n})\n\ndescribe(\"Tests if README's examples work\", () => {\n  const okValue = 3\n  const errValue = \"err!\"\n  function good(): Result<number, string> {\n    return ok(okValue)\n  }\n  function bad(): Result<number, string> {\n    return err(errValue)\n  }\n  function promiseGood(): Promise<Result<number, string>> {\n    return Promise.resolve(ok(okValue))\n  }\n  function promiseBad(): Promise<Result<number, string>> {\n    return Promise.resolve(err(errValue))\n  }\n  function asyncGood(): ResultAsync<number, string> {\n    return okAsync(okValue)\n  }\n  function asyncBad(): ResultAsync<number, string> {\n    return errAsync(errValue)\n  }\n\n  test(\"mayFail2 error\", () => {\n    function myFunc(): Result<number, string> {\n      return safeTry<number, string>(function*() {\n        return ok(\n          (yield* good()\n            .mapErr(e => `1st, ${e}`)\n            .safeUnwrap())\n          +\n          (yield* bad()\n            .mapErr(e => `2nd, ${e}`)\n            .safeUnwrap())\n        )\n      })\n    }\n\n    const result = myFunc()\n    expect(result.isErr()).toBe(true)\n    expect(result._unsafeUnwrapErr()).toBe(`2nd, ${errValue}`)\n  })\n\n  test(\"all ok\", () => {\n    function myFunc(): Result<number, string> {\n      return safeTry<number, string>(function*() {\n        return ok(\n          (yield* good()\n            .mapErr(e => `1st, ${e}`)\n            .safeUnwrap())\n          +\n          (yield* good()\n            .mapErr(e => `2nd, ${e}`)\n            .safeUnwrap())\n        )\n      })\n    }\n\n    const result = myFunc()\n    expect(result.isOk()).toBe(true)\n    expect(result._unsafeUnwrap()).toBe(okValue + okValue)\n  })\n\n  test(\"async mayFail1 error\", async () => {\n    function myFunc(): ResultAsync<number, string> {\n      return safeTry<number, string>(async function*() {\n        return ok(\n          (yield* (await promiseBad())\n            .mapErr(e => `1st, ${e}`)\n            .safeUnwrap())\n          +\n          (yield* asyncGood()\n            .mapErr(e => `2nd, ${e}`)\n            .safeUnwrap())\n        )\n      })\n    }\n\n    const result = await myFunc()\n    expect(result.isErr()).toBe(true)\n    expect(result._unsafeUnwrapErr()).toBe(`1st, ${errValue}`)\n  })\n\n  test(\"async mayFail2 error\", async () => {\n    function myFunc(): ResultAsync<number, string> {\n      return safeTry<number, string>(async function*() {\n        return ok(\n          (yield* (await promiseGood())\n            .mapErr(e => `1st, ${e}`)\n            .safeUnwrap())\n          +\n          (yield* asyncBad()\n            .mapErr(e => `2nd, ${e}`)\n            .safeUnwrap())\n        )\n      })\n    }\n\n    const result = await myFunc()\n    expect(result.isErr()).toBe(true)\n    expect(result._unsafeUnwrapErr()).toBe(`2nd, ${errValue}`)\n  })\n\n  test(\"promise async all ok\", async () => {\n    function myFunc(): ResultAsync<number, string> {\n      return safeTry<number, string>(async function*() {\n        return ok(\n          (yield* (await promiseGood())\n            .mapErr(e => `1st, ${e}`)\n            .safeUnwrap())\n          +\n          (yield* asyncGood()\n            .mapErr(e => `2nd, ${e}`)\n            .safeUnwrap())\n        )\n      })\n    }\n\n    const result = await myFunc()\n    expect(result.isOk()).toBe(true)\n    expect(result._unsafeUnwrap()).toBe(okValue + okValue)\n  })\n})\n\ndescribe(\"it yields and works without safeUnwrap\", () => {\n\ttest(\"With synchronous Ok\", () => {\n\t\tconst res: Result<string, string> = ok(\"ok\");\n\n\t\tconst actual = safeTry(function* () {\n\t\t\tconst x = yield* res;\n\t\t\treturn ok(x);\n\t\t});\n\n\t\texpect(actual).toBeInstanceOf(Ok);\n\t\texpect(actual._unsafeUnwrap()).toBe(\"ok\");\n\t});\n\n\ttest(\"With synchronous Err\", () => {\n\t\tconst res: Result<number, string> = err(\"error\");\n\n\t\tconst actual = safeTry(function* () {\n\t\t\tconst x = yield* res;\n\t\t\treturn ok(x);\n\t\t});\n\n\t\texpect(actual).toBeInstanceOf(Err);\n\t\texpect(actual._unsafeUnwrapErr()).toBe(\"error\");\n\t});\n\n\tconst okValue = 3;\n\tconst errValue = \"err!\";\n\n\tfunction good(): Result<number, string> {\n\t\treturn ok(okValue);\n\t}\n\tfunction bad(): Result<number, string> {\n\t\treturn err(errValue);\n\t}\n\tfunction promiseGood(): Promise<Result<number, string>> {\n\t\treturn Promise.resolve(ok(okValue));\n\t}\n\tfunction promiseBad(): Promise<Result<number, string>> {\n\t\treturn Promise.resolve(err(errValue));\n\t}\n\tfunction asyncGood(): ResultAsync<number, string> {\n\t\treturn okAsync(okValue);\n\t}\n\tfunction asyncBad(): ResultAsync<number, string> {\n\t\treturn errAsync(errValue);\n\t}\n\n\ttest(\"mayFail2 error\", () => {\n\t\tfunction fn(): Result<number, string> {\n\t\t\treturn safeTry<number, string>(function* () {\n\t\t\t\tconst first = yield* good().mapErr((e) => `1st, ${e}`);\n\t\t\t\tconst second = yield* bad().mapErr((e) => `2nd, ${e}`);\n\n\t\t\t\treturn ok(first + second);\n\t\t\t});\n\t\t}\n\n\t\tconst result = fn();\n\t\texpect(result.isErr()).toBe(true);\n\t\texpect(result._unsafeUnwrapErr()).toBe(`2nd, ${errValue}`);\n\t});\n\n\ttest(\"all ok\", () => {\n\t\tfunction myFunc(): Result<number, string> {\n\t\t\treturn safeTry<number, string>(function* () {\n\t\t\t\tconst first = yield* good().mapErr((e) => `1st, ${e}`);\n\t\t\t\tconst second = yield* good().mapErr((e) => `2nd, ${e}`);\n\t\t\t\treturn ok(first + second);\n\t\t\t});\n\t\t}\n\n\t\tconst result = myFunc();\n\t\texpect(result.isOk()).toBe(true);\n\t\texpect(result._unsafeUnwrap()).toBe(okValue + okValue);\n\t});\n\n\ttest(\"async mayFail1 error\", async () => {\n\t\tfunction myFunc(): ResultAsync<number, string> {\n\t\t\treturn safeTry<number, string>(async function* () {\n\t\t\t\tconst first = yield* (await promiseBad()).mapErr((e) => `1st, ${e}`);\n\t\t\t\tconst second = yield* asyncGood().mapErr((e) => `2nd, ${e}`);\n\t\t\t\treturn ok(first + second);\n\t\t\t});\n\t\t}\n\n\t\tconst result = await myFunc();\n\t\texpect(result.isErr()).toBe(true);\n\t\texpect(result._unsafeUnwrapErr()).toBe(`1st, ${errValue}`);\n\t});\n\n\ttest(\"async mayFail2 error\", async () => {\n\t\tfunction myFunc(): ResultAsync<number, string> {\n\t\t\treturn safeTry<number, string>(async function* () {\n\t\t\t\tconst goodResult = await promiseGood();\n\t\t\t\tconst value = yield* goodResult.mapErr((e) => `1st, ${e}`);\n\t\t\t\tconst value2 = yield* asyncBad().mapErr((e) => `2nd, ${e}`);\n\n\t\t\t\treturn okAsync(value + value2);\n\t\t\t});\n\t\t}\n\n\t\tconst result = await myFunc();\n\t\texpect(result.isErr()).toBe(true);\n\t\texpect(result._unsafeUnwrapErr()).toBe(`2nd, ${errValue}`);\n\t});\n\n\ttest(\"promise async all ok\", async () => {\n\t\tfunction myFunc(): ResultAsync<number, string> {\n\t\t\treturn safeTry<number, string>(async function* () {\n\t\t\t\tconst first = yield* (await promiseGood()).mapErr((e) => `1st, ${e}`);\n\t\t\t\tconst second = yield* asyncGood().mapErr((e) => `2nd, ${e}`);\n\t\t\t\treturn ok(first + second);\n\t\t\t});\n\t\t}\n\n\t\tconst result = await myFunc();\n\t\texpect(result.isOk()).toBe(true);\n\t\texpect(result._unsafeUnwrap()).toBe(okValue + okValue);\n\t});\n})\n"
  },
  {
    "path": "tests/tsconfig.tests.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"es2016\",\n    \"module\": \"ES2015\",\n    \"noImplicitAny\": true,\n    \"sourceMap\": false,\n    \"downlevelIteration\": true,\n    \"noUnusedLocals\": false,\n    \"noUnusedParameters\": false,\n    \"strictNullChecks\": true,\n    \"strictFunctionTypes\": true,\n    \"declaration\": true,\n    \"moduleResolution\": \"Node\",\n    \"baseUrl\": \"./src\",\n    \"lib\": [\n      \"dom\",\n      \"es2016\",\n      \"es2017.object\"\n    ],\n    \"outDir\": \"dist\",\n    \"skipLibCheck\": true\n  },\n  \"include\": [\n    \"./index.test.ts\",\n    \"./typecheck-tests.ts\"\n  ]\n}\n"
  },
  {
    "path": "tests/typecheck-tests.ts",
    "content": "/*\n * Type Tests\n *\n * This file is ran during CI to ensure that there aren't breaking changes with types\n */\n\nimport {\n  err,\n  errAsync,\n  fromSafePromise,\n  ok,\n  okAsync,\n  Result,\n  ResultAsync,\n} from '../src'\nimport { safeTry, Transpose } from '../src/result'\nimport { type N, Test } from 'ts-toolbelt'\n\ntype CreateTuple<L, V = string> =\n  // Length must always be a number\n  L extends number\n    ? N.IsNegative<L> extends 1\n      // Length must always be non-negative\n      ? never \n      // base case\n      : L extends 0\n        ? []\n        // recursion depth check\n        // typescript has a limit.\n        : N.Lower<L, 50> extends 1\n          ? [V, ...CreateTuple<N.Sub<L, 1>, V>] \n          : never\n    : never;\n\n\n(function describe(_ = 'Result') {\n  (function describe(_ = 'andThen') {\n    (function it(_ = 'Combines two equal error types (native scalar types)') {\n      type Expectation = Result<unknown, string>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThen((val) => err('yoooooo dude' + val))\n    });\n\n    (function it(_ = 'Combines two equal error types (custom types)') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = Result<string, MyError>\n\n      const result: Expectation = ok<number, MyError>(123)\n        .andThen((val) => err<string, MyError>({ stack: '/blah', code: 500 }))\n    });\n\n    (function it(_ = 'Creates a union of error types for disjoint types') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = Result<string, MyError | string[]>\n\n      const result: Expectation = ok<number, MyError>(123)\n        .andThen((val) => err<string, string[]>(['oh nooooo']))\n    });\n\n    (function it(_ = 'Infers error type when returning disjoint types (native scalar types)') {\n      type Expectation = Result<unknown, string | number | boolean>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThen((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            case 2:\n              return err(123)\n            default:\n              return err(false)\n          }\n        })\n    });\n\n    (function it(_ = 'Infers error type when returning disjoint types (custom types)') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n      type Expectation = Result<unknown, string | number | MyError>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThen((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            case 2:\n              return err(123)\n            default:\n              return err({ stack: '/blah', code: 500 })\n          }\n        })\n    });\n\n    (function it(_ = 'Infers new ok type when returning both Ok and Err (same as initial)') {\n      type Expectation = Result<number, unknown>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThen((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            default:\n              return ok(val + 456)\n          }\n        })\n    });\n\n    (function it(_ = 'Infers new ok type when returning both Ok and Err (different from initial)') {\n      const initial = ok<number, string>(123)\n      type Expectation = Result<string, unknown>\n\n      const result: Expectation = initial\n        .andThen((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            default:\n              return ok(val + ' string')\n          }\n        })\n    });\n\n    (function it(_ = 'Infers new err type when returning both Ok and Err') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n      type Expectation = Result<unknown, string | number | MyError>\n  \n      const result: Expectation = ok<number, string>(123)\n        .andThen((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            case 2:\n              return ok(123)\n            default:\n              return err({ stack: '/blah', code: 500 })\n          }\n        })\n    });\n\n    (function it(_ = 'allows specifying the E and T types explicitly') {\n      type Expectation = Result<'yo', number>\n\n      const result: Expectation = ok(123).andThen<'yo', number>(val => {\n        return ok('yo')\n      })\n    });\n  });\n\n  (function describe(_ = 'andThrough') {\n    (function it(_ = 'Combines two equal error types (native scalar types)') {\n      type Expectation = Result<number, string>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThrough((val) => err('yoooooo dude' + val))\n    });\n\n    (function it(_ = 'Combines two equal error types (custom types)') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = Result<number, MyError>\n\n      const result: Expectation = ok<number, MyError>(123)\n        .andThrough((val) => err<string, MyError>({ stack: '/blah', code: 500 }))\n    });\n\n    (function it(_ = 'Creates a union of error types for disjoint types') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = Result<number, MyError | string[]>\n\n      const result: Expectation = ok<number, MyError>(123)\n        .andThrough((val) => err<string, string[]>(['oh nooooo']))\n    });\n\n    (function it(_ = 'Infers error type when returning disjoint types (native scalar types)') {\n      type Expectation = Result<number, string | number | boolean>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThrough((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            case 2:\n              return err(123)\n            default:\n              return err(false)\n          }\n        })\n    });\n\n    (function it(_ = 'Infers error type when returning disjoint types (custom types)') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n      type Expectation = Result<number, string | number | MyError>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThrough((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            case 2:\n              return err(123)\n            default:\n              return err({ stack: '/blah', code: 500 })\n          }\n        })\n    });\n\n    (function it(_ = 'Returns the original ok type when returning both Ok and Err (same as initial)') {\n      type Expectation = Result<number, unknown>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThrough((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            default:\n              return ok(val + 456)\n          }\n        })\n    });\n\n    (function it(_ = 'Returns the original ok type when returning both Ok and Err (different from initial)') {\n      const initial = ok<number, string>(123)\n      type Expectation = Result<number, unknown>\n\n      const result: Expectation = initial\n        .andThrough((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            default:\n              return ok(\"Hi\" + val)\n          }\n        })\n    });\n\n    (function it(_ = 'Infers new err type when returning both Ok and Err') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n      type Expectation = Result<number, string | number | MyError>\n  \n      const result: Expectation = ok<number, string>(123)\n        .andThrough((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            case 2:\n              return ok(123)\n            default:\n              return err({ stack: '/blah', code: 500 })\n          }\n        })\n    });\n\n    (function it(_ = 'allows specifying the E type explicitly') {\n      type Expectation = Result<number, string>\n\n      const result: Expectation = ok(123).andThrough<string>(val => {\n        return ok('yo')\n      })\n    });\n  });\n\n  (function describe(_ = 'orElse') {\n    (function it(_ = 'the type of the argument is the error type of the result') {\n      type Expectation = string\n\n      const result = ok<number, string>(123)\n        .orElse((val: Expectation) => {\n          switch (val) {\n            case '2':\n              return err(1)\n            default:\n              return err(1)\n          }\n        })\n    });\n\n\n    (function it(_ = 'infers the err return type with multiple returns (same type) ') {\n      type Expectation = Result<number, number>\n\n      const result: Expectation = ok<number, string>(123)\n        .orElse((val) => {\n          switch (val) {\n            case '2':\n              return err(1)\n            default:\n              return err(1)\n          }\n        })\n    });\n\n    (function it(_ = 'infers the err return type with multiple returns (different type) ') {\n      type Expectation = Result<number, number | string>\n\n      const result: Expectation = ok<number, string>(123)\n        .orElse((val) => {\n          switch (val) {\n            case '2':\n              return err(1)\n            default:\n              return err('1')\n          }\n        })\n    });\n\n    (function it(_ = 'infers ok and err return types with multiple returns ') {\n      type Expectation = Result<number, number | string>\n\n      const result: Expectation = ok<number, string>(123)\n        .orElse((val) => {\n          switch (val) {\n            case '1':\n              return ok(1)\n            case '2':\n              return err(1)\n            default:\n              return err('1')\n          }\n        })\n    });\n\n    (function it(_ = 'allows specifying the E and T types explicitly') {\n      type Expectation = Result<'yo', string>\n\n      const result: Expectation = ok<'yo', number>('yo').orElse<'yo', string>(val => {\n        return err('yo')\n      })\n    });\n\n    (function it(_ = 'Creates a union of ok types for disjoint types') {\n      type Expectation = Result<string | number, boolean>\n\n      const result: Expectation = err<string, boolean[]>([true])\n          .orElse((val) => ok<string, boolean>('recovered!'))\n    });\n\n    (function it(_ = 'Infers ok type when returning disjoint types') {\n      type Expectation = Result<string | number | boolean, unknown>\n\n      const result: Expectation = err<string, number>(123)\n          .orElse((val) => {\n            switch (val) {\n              case 1:\n                return ok('yoooooo dude' + val)\n              case 2:\n                return ok(123)\n              default:\n                return ok(false)\n            }\n          })\n    });\n\n    (function it(_ = 'Infers new type when returning both Ok and Err') {\n      const initial = err<string, number>(123)\n      type Expectation = Result<string | true, false>\n\n      const result: Expectation = initial\n          .orElse((val) => {\n            switch (val) {\n              case 1:\n                return err(false as const)\n              default:\n                return ok(true as const)\n            }\n          })\n    });\n  });\n\n  (function describe(_ = 'match') {\n    (function it(_ = 'the type of the arguments match the types of the result') {\n      type OKExpectation = number\n      type ErrExpectation = string\n\n      ok<number, string>(123)\n        .match(\n          (val: OKExpectation): void => void val,\n          (val: ErrExpectation): void => void val,\n        );\n      err<number, string>(\"123\")\n        .match(\n          (val: OKExpectation): void => void val,\n          (val: ErrExpectation): void => void val,\n        );\n    });\n\n    (function it(_ = 'infers the resulting value from match callbacks (same type)') {\n      type Expectation = boolean\n\n      const okResult: Expectation = ok<number, string>(123)\n        .match(\n          (val) => !!val,\n          (val) => !!val,\n        );\n      const errResult: Expectation = err<number, string>('123')\n        .match(\n          (val) => !!val,\n          (val) => !!val,\n        );\n    });\n\n    (function it(_ = 'infers the resulting value from match callbacks (different type)') {\n      type Expectation = boolean | bigint\n\n      const okResult: Expectation = ok<string, number>('123')\n        .match(\n          (val) => !!val,\n          (val) => BigInt(val),\n        );\n      const errResult: Expectation = err<string, number>(123)\n        .match(\n          (val) => !!val,\n          (val) => BigInt(val),\n        );\n    });\n  });\n\n  (function describe(_ = 'asyncAndThen') {\n    (function it(_ = 'Combines two equal error types (native scalar types)') {\n      type Expectation = ResultAsync<unknown, string>\n\n      const result: Expectation = ok<number, string>(123)\n        .asyncAndThen((val) => errAsync('yoooooo dude' + val))\n    });\n\n    (function it(_ = 'Combines two equal error types (custom types)') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = ResultAsync<string, MyError>\n\n      const result: Expectation = ok<number, MyError>(123)\n        .asyncAndThen((val) => errAsync<string, MyError>({ stack: '/blah', code: 500 }))\n    });\n\n    (function it(_ = 'Creates a union of error types for disjoint types') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = ResultAsync<string, MyError | string[]>\n\n      const result: Expectation = ok<number, MyError>(123)\n        .asyncAndThen((val) => errAsync<string, string[]>(['oh nooooo']))\n    });\n  });\n\n  (function describe(_ = 'asyncAndThrough') {\n    (function it(_ = 'Combines two equal error types (native scalar types)') {\n      type Expectation = ResultAsync<unknown, string>\n\n      const result: Expectation = ok<number, string>(123)\n        .asyncAndThrough((val) => errAsync('yoooooo dude' + val))\n    });\n\n    (function it(_ = 'Combines two equal error types (custom types)') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = ResultAsync<number, MyError>\n\n      const result: Expectation = ok<number, MyError>(123)\n        .asyncAndThrough((val) => errAsync<string, MyError>({ stack: '/blah', code: 500 }))\n    });\n\n    (function it(_ = 'Creates a union of error types for disjoint types') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = ResultAsync<number, MyError | string[]>\n\n      const result: Expectation = ok<number, MyError>(123)\n        .asyncAndThrough((val) => errAsync<string, string[]>(['oh nooooo']))\n    });\n\n    (function it(_ = 'Infers error type when returning disjoint types (native scalar types)') {\n      type Expectation = ResultAsync<number, string | number | boolean>\n\n      const result: Expectation = ok<number, string>(123)\n        .asyncAndThrough((val) => {\n          switch (val) {\n            case 1:\n              return errAsync('yoooooo dude' + val)\n            case 2:\n              return errAsync(123)\n            default:\n              return errAsync(false)\n          }\n        })\n    });\n\n    (function it(_ = 'Infers error type when returning disjoint types (custom types)') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n      type Expectation = Result<number, string | number | MyError>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThrough((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            case 2:\n              return err(123)\n            default:\n              return err({ stack: '/blah', code: 500 })\n          }\n        })\n    });\n\n    (function it(_ = 'Returns the original ok type when returning both Ok and Err (same as initial)') {\n      type Expectation = Result<number, unknown>\n\n      const result: Expectation = ok<number, string>(123)\n        .andThrough((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            default:\n              return ok(val + 456)\n          }\n        })\n    });\n\n    (function it(_ = 'Returns the original ok type when returning both Ok and Err (different from initial)') {\n      const initial = ok<number, string>(123)\n      type Expectation = Result<number, unknown>\n\n      const result: Expectation = initial\n        .andThrough((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            default:\n              return ok(\"Hi\" + val)\n          }\n        })\n    });\n\n    (function it(_ = 'Infers new err type when returning both Ok and Err') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n      type Expectation = Result<number, string | number | MyError>\n  \n      const result: Expectation = ok<number, string>(123)\n        .andThrough((val) => {\n          switch (val) {\n            case 1:\n              return err('yoooooo dude' + val)\n            case 2:\n              return ok(123)\n            default:\n              return err({ stack: '/blah', code: 500 })\n          }\n        })\n    });\n\n    (function it(_ = 'allows specifying the E type explicitly') {\n      type Expectation = Result<number, string>\n\n      const result: Expectation = ok(123).andThrough<string>(val => {\n        return ok('yo')\n      })\n    });\n\n\n    (function it(_ = 'Infers new err type when returning both Ok and Err') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n      type Expectation = ResultAsync<number, string | number | MyError>\n  \n      const result: Expectation = ok<number, string>(123)\n        .asyncAndThrough((val) => {\n          switch (val) {\n            case 1:\n              return errAsync('yoooooo dude' + val)\n            case 2:\n              return okAsync(123)\n            default:\n              return errAsync({ stack: '/blah', code: 500 })\n          }\n        })\n    });\n\n\n  });\n\n  (function describe(_ = 'combine') {\n    (function it(_ = 'combines different results into one') {\n      type Expectation = Result<[ number, string, boolean, boolean ], Error | string | string[]>;\n\n      const result = Result.combine([\n        ok<number, string>(1),\n        ok<string, string>('string'),\n        err<boolean, string[]>([ 'string', 'string2' ]),\n        err<boolean, Error>(new Error('error content')),\n      ])\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines only ok results into one') {\n      type Expectation = Result<[ number, string ], never>;\n\n      const result = Result.combine([\n        ok(1),\n        ok('string'),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines only err results into one') {\n      type Expectation = Result<[ never, never ], number | 'abc'>;\n\n      const result = Result.combine([\n        err(1),\n        err('abc'),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines empty list results into one') {\n      type Expectation = Result<never, never>;\n      const results: [] = [];\n\n      const result = Result.combine(results);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines arrays of results to a result of an array') {\n      type Expectation = Result<string[], string>;\n      const results: Result<string, string>[] = [];\n\n      const result = Result.combine(results);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function describe(_ = 'inference on large tuples') {\n      (function it(_ = 'Should correctly infer the type on tuples with 6 elements') {\n        type Input = CreateTuple<6, Result<string, never>>\n        type Expectation = Result<CreateTuple<6, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 7 elements') {\n        type Input = CreateTuple<7, Result<string, never>>\n        type Expectation = Result<CreateTuple<7, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 8 elements') {\n        type Input = CreateTuple<8, Result<string, never>>\n        type Expectation = Result<CreateTuple<8, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 9 elements') {\n        type Input = CreateTuple<9, Result<string, never>>\n        type Expectation = Result<CreateTuple<9, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 10 elements') {\n        type Input = CreateTuple<10, Result<string, never>>\n        type Expectation = Result<CreateTuple<10, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 11 elements') {\n        type Input = CreateTuple<11, Result<string, never>>\n        type Expectation = Result<CreateTuple<11, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 12 elements') {\n        type Input = CreateTuple<12, Result<string, never>>\n        type Expectation = Result<CreateTuple<12, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 13 elements') {\n        type Input = CreateTuple<13, Result<string, never>>\n        type Expectation = Result<CreateTuple<13, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 14 elements') {\n        type Input = CreateTuple<14, Result<string, never>>\n        type Expectation = Result<CreateTuple<14, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 15 elements') {\n        type Input = CreateTuple<15, Result<string, never>>\n        type Expectation = Result<CreateTuple<15, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 16 elements') {\n        type Input = CreateTuple<16, Result<string, never>>\n        type Expectation = Result<CreateTuple<16, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 17 elements') {\n        type Input = CreateTuple<17, Result<string, never>>\n        type Expectation = Result<CreateTuple<17, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 18 elements') {\n        type Input = CreateTuple<18, Result<string, never>>\n        type Expectation = Result<CreateTuple<18, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 19 elements') {\n        type Input = CreateTuple<19, Result<string, never>>\n        type Expectation = Result<CreateTuple<19, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 20 elements') {\n        type Input = CreateTuple<20, Result<string, never>>\n        type Expectation = Result<CreateTuple<20, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 21 elements') {\n        type Input = CreateTuple<21, Result<string, never>>\n        type Expectation = Result<CreateTuple<21, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 22 elements') {\n        type Input = CreateTuple<22, Result<string, never>>\n        type Expectation = Result<CreateTuple<22, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 23 elements') {\n        type Input = CreateTuple<23, Result<string, never>>\n        type Expectation = Result<CreateTuple<23, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 24 elements') {\n        type Input = CreateTuple<24, Result<string, never>>\n        type Expectation = Result<CreateTuple<24, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 25 elements') {\n        type Input = CreateTuple<25, Result<string, never>>\n        type Expectation = Result<CreateTuple<25, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 26 elements') {\n        type Input = CreateTuple<26, Result<string, never>>\n        type Expectation = Result<CreateTuple<26, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 27 elements') {\n        type Input = CreateTuple<27, Result<string, never>>\n        type Expectation = Result<CreateTuple<27, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 28 elements') {\n        type Input = CreateTuple<28, Result<string, never>>\n        type Expectation = Result<CreateTuple<28, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 29 elements') {\n        type Input = CreateTuple<29, Result<string, never>>\n        type Expectation = Result<CreateTuple<29, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 30 elements') {\n        type Input = CreateTuple<30, Result<string, never>>\n        type Expectation = Result<CreateTuple<30, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 31 elements') {\n        type Input = CreateTuple<31, Result<string, never>>\n        type Expectation = Result<CreateTuple<31, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 32 elements') {\n        type Input = CreateTuple<32, Result<string, never>>\n        type Expectation = Result<CreateTuple<32, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 33 elements') {\n        type Input = CreateTuple<33, Result<string, never>>\n        type Expectation = Result<CreateTuple<33, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 34 elements') {\n        type Input = CreateTuple<34, Result<string, never>>\n        type Expectation = Result<CreateTuple<34, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 35 elements') {\n        type Input = CreateTuple<35, Result<string, never>>\n        type Expectation = Result<CreateTuple<35, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 36 elements') {\n        type Input = CreateTuple<36, Result<string, never>>\n        type Expectation = Result<CreateTuple<36, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 37 elements') {\n        type Input = CreateTuple<37, Result<string, never>>\n        type Expectation = Result<CreateTuple<37, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 38 elements') {\n        type Input = CreateTuple<38, Result<string, never>>\n        type Expectation = Result<CreateTuple<38, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 39 elements') {\n        type Input = CreateTuple<39, Result<string, never>>\n        type Expectation = Result<CreateTuple<39, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 40 elements') {\n        type Input = CreateTuple<40, Result<string, never>>\n        type Expectation = Result<CreateTuple<40, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 41 elements') {\n        type Input = CreateTuple<41, Result<string, never>>\n        type Expectation = Result<CreateTuple<41, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 42 elements') {\n        type Input = CreateTuple<42, Result<string, never>>\n        type Expectation = Result<CreateTuple<42, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 43 elements') {\n        type Input = CreateTuple<43, Result<string, never>>\n        type Expectation = Result<CreateTuple<43, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 44 elements') {\n        type Input = CreateTuple<44, Result<string, never>>\n        type Expectation = Result<CreateTuple<44, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 45 elements') {\n        type Input = CreateTuple<45, Result<string, never>>\n        type Expectation = Result<CreateTuple<45, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 46 elements') {\n        type Input = CreateTuple<46, Result<string, never>>\n        type Expectation = Result<CreateTuple<46, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 47 elements') {\n        type Input = CreateTuple<47, Result<string, never>>\n        type Expectation = Result<CreateTuple<47, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 48 elements') {\n        type Input = CreateTuple<48, Result<string, never>>\n        type Expectation = Result<CreateTuple<48, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 49 elements') {\n        type Input = CreateTuple<49, Result<string, never>>\n        type Expectation = Result<CreateTuple<49, string>, never>\n\n        const inputValues = input<Input>()\n        const result = Result.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n    });\n  });\n\n  (function describe(_ = 'combineWithAllErrors') {\n    (function it(_ = 'combines different results into one') {\n      type Expectation = Result<[ number, string, never, never ], (string[] | Error)[]>;\n\n      const result = Result.combineWithAllErrors([\n        ok(1),\n        ok('string'),\n        err([ 'string', 'string2' ]),\n        err(new Error('error content')),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines only ok results into one') {\n      type Expectation = Result<[ number, string ], never[]>;\n\n      const result = Result.combineWithAllErrors([\n        ok(1),\n        ok('string'),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines only err results into one') {\n      type Expectation = Result<[ never, never ], (number | 'string')[]>;\n\n      const result = Result.combineWithAllErrors([\n        err(1),\n        err('string'),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines arrays of results to a result of an array') {\n      type Expectation = Result<string[], (number | string)[]>;\n      const results: Result<string, number | string>[] = [];\n\n      const result = Result.combineWithAllErrors(results);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines arrays of different results to a result of an array') {\n      type Expectation = Result<(string | boolean)[], (number | string)[]>;\n      const results: (Result<string, number> | Result<boolean, string>)[] = [];\n\n      const result = Result.combineWithAllErrors(results);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function describe(_ = 'inference on large tuples') {\n      (function it(_ = 'Should correctly infer the type on tuples with 6 elements') {\n        type Input = CreateTuple<6, Result<string, number>>\n        type Expectation = Result<CreateTuple<6, string>, number[]>\n\n        const inputValues = input<Input>()\n        const result = Result.combineWithAllErrors(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 15 elements') {\n        type Input = CreateTuple<15, Result<string, number>>\n        type Expectation = Result<CreateTuple<15, string>, number[]>\n\n        const inputValues = input<Input>()\n        const result = Result.combineWithAllErrors(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 30 elements') {\n        type Input = CreateTuple<30, Result<string, number>>\n        type Expectation = Result<CreateTuple<30, string>, number[]>\n\n        const inputValues = input<Input>()\n        const result = Result.combineWithAllErrors(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 49 elements') {\n        type Input = CreateTuple<49 , Result<string, number>>\n        type Expectation = Result<CreateTuple<49, string>, number[]>\n\n        const inputValues = input<Input>()\n        const result = Result.combineWithAllErrors(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n    });\n  });\n\n  (function describe(_ = 'err') {\n    (function it(_ = 'infers the error type narrowly when it is a string') {\n      type Expectation = Result<never, 'error'>\n\n      const result = err('error')\n\n      const assignableToCheck: Expectation = result;\n    });\n\n    (function it(_ = 'infers the error type widely when it is not a string') {\n      type Expectation = Result<never, { abc: number }>\n\n      const result = err({ abc: 123 })\n\n      const assignableToCheck: Expectation = result;\n    });\n  })\n});\n\n\n(function describe(_ = 'ResultAsync') {\n  (function describe(_ = 'andThen') {\n    (function it(_ = 'Combines two equal error types (native scalar types)') {\n      type Expectation = ResultAsync<unknown, string>\n\n      const result: Expectation = okAsync<number, string>(123)\n        .andThen((val) => err('yoooooo dude' + val))\n    });\n\n    (function it(_ = 'Combines two equal error types (custom types)') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = ResultAsync<string, MyError>\n\n      const result: Expectation = okAsync<number, MyError>(123)\n        .andThen((val) => err<string, MyError>({ stack: '/blah', code: 500 }))\n    });\n\n    (function it(_ = 'Creates a union of error types for disjoint types') {\n      interface MyError { \n        stack: string\n        code: number\n      }\n\n      type Expectation = ResultAsync<string, MyError | string[]>\n\n      const result: Expectation = okAsync<number, MyError>(123)\n        .andThen((val) => err<string, string[]>(['oh nooooo']))\n    });\n\n    (function describe(_ = 'when returning Result types') {\n      (function it(_ = 'Infers error type when returning disjoint types (native scalar types)') {\n        type Expectation = ResultAsync<unknown, string | number | boolean>\n  \n        const result: Expectation = okAsync<number, string>(123)\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return err('yoooooo dude' + val)\n              case 2:\n                return err(123)\n              default:\n                return err(false)\n            }\n          })\n      });\n  \n      (function it(_ = 'Infers error type when returning disjoint types (custom types)') {\n        interface MyError { \n          stack: string\n          code: number\n        }\n        type Expectation = ResultAsync<unknown, string | number | MyError>\n  \n        const result: Expectation = okAsync<number, string>(123)\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return err('yoooooo dude' + val)\n              case 2:\n                return err(123)\n              default:\n                return err({ stack: '/blah', code: 500 })\n            }\n          })\n      });\n  \n      (function it(_ = 'Infers new ok type when returning both Ok and Err (same as initial)') {\n        type Expectation = ResultAsync<number, unknown>\n  \n        const result: Expectation = okAsync<number, string>(123)\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return err('yoooooo dude' + val)\n              default:\n                return ok(val + 456)\n            }\n          })\n      });\n  \n      (function it(_ = 'Infers new ok type when returning both Ok and Err (different from initial)') {\n        const initial = okAsync<number, string>(123)\n        type Expectation = ResultAsync<string, unknown>\n  \n        const result: Expectation = initial\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return err('yoooooo dude' + val)\n              default:\n                return ok(val + ' string')\n            }\n          })\n      });\n  \n      (function it(_ = 'Infers new err type when returning both Ok and Err') {\n        interface MyError { \n          stack: string\n          code: number\n        }\n        type Expectation = ResultAsync<unknown, string | number | MyError>\n    \n        const result: Expectation = okAsync<number, string>(123)\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return err('yoooooo dude' + val)\n              case 2:\n                return ok(123)\n              default:\n                return err({ stack: '/blah', code: 500 })\n            }\n          })\n      });\n    });\n\n    (function describe(_ = 'when returning ResultAsync types') {\n      (function it(_ = 'Infers error type when returning disjoint types (native scalar types)') {\n        type Expectation = ResultAsync<unknown, string | number | boolean>\n  \n        const result: Expectation = okAsync<number, string>(123)\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return errAsync('yoooooo dude' + val)\n              case 2:\n                return errAsync(123)\n              default:\n                return errAsync(false)\n            }\n          })\n      });\n  \n      (function it(_ = 'Infers error type when returning disjoint types (custom types)') {\n        interface MyError { \n          stack: string\n          code: number\n        }\n        type Expectation = ResultAsync<unknown, string | number | MyError>\n  \n        const result: Expectation = okAsync<number, string>(123)\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return errAsync('yoooooo dude' + val)\n              case 2:\n                return errAsync(123)\n              default:\n                return errAsync({ stack: '/blah', code: 500 })\n            }\n          })\n      });\n  \n      (function it(_ = 'Infers new ok type when returning both Ok and Err (same as initial)') {\n        type Expectation = ResultAsync<number, unknown>\n  \n        const result: Expectation = okAsync<number, string>(123)\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return errAsync('yoooooo dude' + val)\n              default:\n                return okAsync(val + 456)\n            }\n          })\n      });\n  \n      (function it(_ = 'Infers new ok type when returning both Ok and Err (different from initial)') {\n        const initial = okAsync<number, string>(123)\n        type Expectation = ResultAsync<string, unknown>\n  \n        const result: Expectation = initial\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return errAsync('yoooooo dude' + val)\n              default:\n                return okAsync(val + ' string')\n            }\n          })\n      });\n  \n      (function it(_ = 'Infers new err type when returning both Ok and Err') {\n        interface MyError { \n          stack: string\n          code: number\n        }\n        type Expectation = ResultAsync<unknown, string | number | MyError>\n    \n        const result: Expectation = okAsync<number, string>(123)\n          .andThen((val) => {\n            switch (val) {\n              case 1:\n                return errAsync('yoooooo dude' + val)\n              case 2:\n                return okAsync(123)\n              default:\n                return errAsync({ stack: '/blah', code: 500 })\n            }\n          })\n      });\n    });\n\n    (function describe(_ = 'when returning a mix of Result and ResultAsync types') {\n      (function it(_ = 'allows for explicitly specifying the Ok and Err types when inference fails') {\n        type Expectation = ResultAsync<number | boolean, string | number | boolean>\n  \n        const result: Expectation = okAsync<number, string>(123)\n          .andThen<number | boolean, string | number | boolean>((val) => {\n            switch (val) {\n              case 1:\n                return errAsync('yoooooo dude' + val)\n              case 2:\n                return err(123)\n              default:\n                return okAsync(false)\n            }\n          })\n      });\n    });\n\n    (function describe(_ = 'fromSafePromise') {\n      (function it(_ = 'infers err type from usage') {\n        type Expectation = ResultAsync<number, 'impossible error'>\n\n        const result: Expectation = fromSafePromise(new Promise<number>((resolve) => resolve(123)))\n          .map((val) => val)\n      });\n    });\n  });\n\n  (function describe(_ = 'orElse') {\n    (function it(_ = 'the type of the argument is the error type of the result') {\n      type Expectation = string\n\n      const result = okAsync<number, string>(123)\n        .orElse((val: Expectation) => {\n          switch (val) {\n            case '2':\n              return errAsync(1)\n            default:\n              return errAsync(1)\n          }\n        })\n    });\n\n\n    (function it(_ = 'infers the err return type with multiple returns (same type) ') {\n      type Expectation = ResultAsync<number, number>\n\n      const result: Expectation = okAsync<number, string>(123)\n        .orElse((val) => {\n          switch (val) {\n            case '2':\n              return errAsync(1)\n            default:\n              return errAsync(1)\n          }\n        })\n    });\n\n    (function it(_ = 'infers the err return type with multiple returns (different type) ') {\n      type Expectation = ResultAsync<number, number | string>\n\n      const result: Expectation = okAsync<number, string>(123)\n        .orElse((val) => {\n          switch (val) {\n            case '2':\n              return errAsync(1)\n            default:\n              return errAsync('1')\n          }\n        })\n    });\n\n    (function it(_ = 'infers ok and err return types with multiple returns ') {\n      type Expectation = ResultAsync<number, number | string>\n\n      const result: Expectation = okAsync<number, string>(123)\n        .orElse((val) => {\n          switch (val) {\n            case '1':\n              return okAsync(1)\n            case '2':\n              return errAsync(1)\n            default:\n              return errAsync('1')\n          }\n        })\n    });\n\n    (function it(_ = 'allows specifying ok and err return types when mixing Result and ResultAsync in returns ') {\n      type Expectation = ResultAsync<number, number | string>\n\n      const result: Expectation = okAsync<number, string>(123)\n        .orElse<number, number | string>((val) => {\n          switch (val) {\n            case '1':\n              return ok(1)\n            case '2':\n              return errAsync(1)\n            default:\n              return errAsync('1')\n          }\n        })\n    });\n\n    (function it(_ = 'Creates a union of ok types for disjoint types') {\n      type Expectation = ResultAsync<string | number, boolean>\n\n      const result: Expectation = errAsync<string, boolean[]>([true])\n          .orElse((val) => ok<string, boolean>('recovered!'))\n    });\n\n    (function it(_ = 'Infers ok type when returning disjoint types') {\n      type Expectation = ResultAsync<string | number | boolean, unknown>\n\n      const result: Expectation = errAsync<string, number>(123)\n          .orElse((val) => {\n            switch (val) {\n              case 1:\n                return okAsync('yoooooo dude' + val)\n              case 2:\n                return okAsync(123)\n              default:\n                return okAsync(false)\n            }\n          })\n    });\n\n    (function it(_ = 'Infers new type when returning both Ok and Err') {\n      const initial = errAsync<string, number>(123)\n      type Expectation = ResultAsync<string | true, false>\n\n      const result: Expectation = initial\n          .orElse((val) => {\n            switch (val) {\n              case 1:\n                return err(false as const)\n              default:\n                return okAsync(true as const)\n            }\n          })\n    });\n  });\n\n  (function describe(_ = 'combine') {\n    (function it(_ = 'combines different result asyncs into one') {\n      type Expectation = ResultAsync<[ number, string, boolean, boolean ], Error | string | string[]>;\n\n      const result = ResultAsync.combine([\n        okAsync<number, string>(1),\n        okAsync<string, string>('string'),\n        errAsync<boolean, string[]>([ 'string', 'string2' ]),\n        errAsync<boolean, Error>(new Error('error content')),\n      ])\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines only ok result asyncs into one') {\n      type Expectation = ResultAsync<[ number, string ], never>;\n\n      const result = ResultAsync.combine([\n        okAsync(1),\n        okAsync('string'),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines only err results into one') {\n      type Expectation = ResultAsync<[ never, never ], number | string>;\n\n      const result = ResultAsync.combine([\n        errAsync(1),\n        errAsync('string'),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines empty list result asyncs into one') {\n      type Expectation = ResultAsync<never, never>;\n      const results: [] = [];\n\n      const result = ResultAsync.combine(results);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines arrays of result asyncs to a result async of an array') {\n      type Expectation = ResultAsync<string[], string>;\n      const results: ResultAsync<string, string>[] = [];\n\n      const result = ResultAsync.combine(results);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function describe(_ = 'inference on large tuples') {\n      (function it(_ = 'Should correctly infer the type on tuples with 6 elements') {\n        type Input = CreateTuple<6, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<6, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 7 elements') {\n        type Input = CreateTuple<7, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<7, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 8 elements') {\n        type Input = CreateTuple<8, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<8, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 9 elements') {\n        type Input = CreateTuple<9, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<9, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 10 elements') {\n        type Input = CreateTuple<10, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<10, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 11 elements') {\n        type Input = CreateTuple<11, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<11, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 12 elements') {\n        type Input = CreateTuple<12, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<12, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 13 elements') {\n        type Input = CreateTuple<13, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<13, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 14 elements') {\n        type Input = CreateTuple<14, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<14, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 15 elements') {\n        type Input = CreateTuple<15, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<15, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 16 elements') {\n        type Input = CreateTuple<16, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<16, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 17 elements') {\n        type Input = CreateTuple<17, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<17, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 18 elements') {\n        type Input = CreateTuple<18, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<18, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 19 elements') {\n        type Input = CreateTuple<19, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<19, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 20 elements') {\n        type Input = CreateTuple<20, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<20, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 21 elements') {\n        type Input = CreateTuple<21, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<21, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 22 elements') {\n        type Input = CreateTuple<22, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<22, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 23 elements') {\n        type Input = CreateTuple<23, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<23, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 24 elements') {\n        type Input = CreateTuple<24, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<24, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 25 elements') {\n        type Input = CreateTuple<25, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<25, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 26 elements') {\n        type Input = CreateTuple<26, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<26, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 27 elements') {\n        type Input = CreateTuple<27, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<27, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 28 elements') {\n        type Input = CreateTuple<28, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<28, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 29 elements') {\n        type Input = CreateTuple<29, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<29, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 30 elements') {\n        type Input = CreateTuple<30, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<30, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 31 elements') {\n        type Input = CreateTuple<31, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<31, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 32 elements') {\n        type Input = CreateTuple<32, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<32, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 33 elements') {\n        type Input = CreateTuple<33, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<33, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 34 elements') {\n        type Input = CreateTuple<34, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<34, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 35 elements') {\n        type Input = CreateTuple<35, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<35, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 36 elements') {\n        type Input = CreateTuple<36, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<36, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 37 elements') {\n        type Input = CreateTuple<37, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<37, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 38 elements') {\n        type Input = CreateTuple<38, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<38, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 39 elements') {\n        type Input = CreateTuple<39, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<39, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 40 elements') {\n        type Input = CreateTuple<40, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<40, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 41 elements') {\n        type Input = CreateTuple<41, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<41, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 42 elements') {\n        type Input = CreateTuple<42, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<42, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 43 elements') {\n        type Input = CreateTuple<43, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<43, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 44 elements') {\n        type Input = CreateTuple<44, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<44, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 45 elements') {\n        type Input = CreateTuple<45, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<45, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 46 elements') {\n        type Input = CreateTuple<46, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<46, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 47 elements') {\n        type Input = CreateTuple<47, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<47, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 48 elements') {\n        type Input = CreateTuple<48, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<48, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 49 elements') {\n        type Input = CreateTuple<49, ResultAsync<string, never>>\n        type Expectation = ResultAsync<CreateTuple<49, string>, never>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combine(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n    });\n  });\n\n  (function describe(_ = 'combineWithAllErrors') {\n    (function it(_ = 'combines different result asyncs into one') {\n      type Expectation = ResultAsync<[ number, string, never, never ], (string[] | Error)[]>;\n\n      const result = ResultAsync.combineWithAllErrors([\n        okAsync(1),\n        okAsync('string'),\n        errAsync([ 'string', 'string2' ]),\n        errAsync(new Error('error content')),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines only ok result asyncs into one') {\n      type Expectation = ResultAsync<[ number, string ], never[]>;\n\n      const result = ResultAsync.combineWithAllErrors([\n        okAsync(1),\n        okAsync('string'),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines only err result asyncs into one') {\n      type Expectation = ResultAsync<[ never, never ], (number | string)[]>;\n\n      const result = ResultAsync.combineWithAllErrors([\n        errAsync(1),\n        errAsync('string'),\n      ]);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines arrays of result asyncs to a result of an array') {\n      type Expectation = ResultAsync<string[], (number | string)[]>;\n      const results: ResultAsync<string, number | string>[] = [];\n\n      const result = ResultAsync.combineWithAllErrors(results);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function it(_ = 'combines arrays of different result asyncs to a result of an array') {\n      type Expectation = ResultAsync<(string | boolean)[], (number | string)[]>;\n      const results: (ResultAsync<string, number> | ResultAsync<boolean, string>)[] = [];\n\n      const result = ResultAsync.combineWithAllErrors(results);\n\n      const assignableToCheck: Expectation = result;\n      const assignablefromCheck: typeof result = assignableToCheck;\n    });\n\n    (function describe(_ = 'inference on large tuples') {\n      (function it(_ = 'Should correctly infer the type on tuples with 6 elements') {\n        type Input = CreateTuple<6, ResultAsync<string, number>>\n        type Expectation = ResultAsync<CreateTuple<6, string>, number[]>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combineWithAllErrors(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 15 elements') {\n        type Input = CreateTuple<15, ResultAsync<string, number>>\n        type Expectation = ResultAsync<CreateTuple<15, string>, number[]>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combineWithAllErrors(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 30 elements') {\n        type Input = CreateTuple<30, ResultAsync<string, number>>\n        type Expectation = ResultAsync<CreateTuple<30, string>, number[]>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combineWithAllErrors(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'Should correctly infer the type on tuples with 49 elements') {\n        type Input = CreateTuple<49 , ResultAsync<string, number>>\n        type Expectation = ResultAsync<CreateTuple<49, string>, number[]>\n\n        const inputValues = input<Input>()\n        const result = ResultAsync.combineWithAllErrors(inputValues)\n\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n    });\n\n\n\n  });\n});\n\n(function describe(_ = 'Utility types') {\n  (function describe(_ = 'safeTry') {\n    (function describe(_ = 'sync generator') {\n      (function it(_ = 'should correctly infer the result type when generator returns Ok') {\n        interface ReturnMyError {\n          name: 'ReturnMyError'\n        }\n\n        type Expectation = Result<string, ReturnMyError>\n\n        const result = safeTry(function *() {\n          return ok<string, ReturnMyError>('string');\n        })\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'should correctly infer the result type when generator returns Err') {\n        interface ReturnMyError {\n          name: 'ReturnMyError';\n        }\n\n        type Expectation = Result<string, ReturnMyError>\n\n        const result = safeTry(function *() {\n          return err<string, ReturnMyError>({ name: 'ReturnMyError' });\n        })\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'infers the value type when calling \"yield*\"') {\n        interface YieldMyError {\n          name: 'YieldMyError';\n        }\n        interface ReturnMyError {\n          name: 'ReturnMyError';\n        }\n\n        safeTry(function *() {\n          type Expectation = number\n\n          const unwrapped = yield* ok<number, YieldMyError>(123).safeUnwrap();\n          Test.checks([\n            Test.check<typeof unwrapped, Expectation, Test.Pass>(),\n          ])\n\n          return ok<string, ReturnMyError>('string');\n        })\n      });\n\n      (function it(_ = 'should correctly infer the result type with multiple \"yield*\"') {\n        interface FirstYieldMyError {\n          name: 'FirstYieldMyError';\n        }\n        interface SecondYieldMyError {\n          name: 'SecondYieldMyError';\n        }\n        interface ReturnMyError {\n          name: 'ReturnMyError';\n        }\n\n        type Expectation = Result<string, FirstYieldMyError | SecondYieldMyError | ReturnMyError>\n\n        const result = safeTry(function *() {\n          yield* ok<number, FirstYieldMyError>(123).safeUnwrap();\n          yield* err<never, SecondYieldMyError>({ name: 'SecondYieldMyError' }).safeUnwrap();\n          return ok<string, ReturnMyError>('string');\n        })\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n    });\n\n    (function describe(_ = 'async generator') {\n      (function it(_ = 'should correctly infer the result type when generator returns OkAsync') {\n        interface ReturnMyError {\n          name: 'ReturnMyError'\n        }\n\n        type Expectation = ResultAsync<string, ReturnMyError>\n\n        const result = safeTry(async function *() {\n          return okAsync<string, ReturnMyError>('string');\n        })\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'should correctly infer the result type when generator returns ErrAsync') {\n        interface ReturnMyError {\n          name: 'ReturnMyError';\n        }\n\n        type Expectation = ResultAsync<string, ReturnMyError>\n\n        const result = safeTry(async function *() {\n          return errAsync<string, ReturnMyError>({ name: 'ReturnMyError' });\n        })\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n\n      (function it(_ = 'infers the value type when calling \"yield*\"') {\n        interface YieldMyError {\n          name: 'YieldMyError';\n        }\n        interface ReturnMyError {\n          name: 'ReturnMyError';\n        }\n\n        safeTry(async function *() {\n          type Expectation = number\n\n          const unwrapped = yield* okAsync<number, YieldMyError>(123).safeUnwrap();\n          Test.checks([\n            Test.check<typeof unwrapped, Expectation, Test.Pass>(),\n          ])\n\n          return ok<string, ReturnMyError>('string');\n        })\n      });\n\n      (function it(_ = 'should correctly infer the result type with multiple \"yield*\"') {\n        interface FirstYieldMyError {\n          name: 'FirstYieldMyError';\n        }\n        interface SecondYieldMyError {\n          name: 'SecondYieldMyError';\n        }\n        interface ReturnMyError {\n          name: 'ReturnMyError';\n        }\n\n        type Expectation = ResultAsync<string, FirstYieldMyError | SecondYieldMyError | ReturnMyError>\n\n        const result = safeTry(async function *() {\n          yield* okAsync<number, FirstYieldMyError>(123).safeUnwrap();\n          yield* errAsync<never, SecondYieldMyError>({ name: 'SecondYieldMyError' }).safeUnwrap();\n          return okAsync<string, ReturnMyError>('string');\n        })\n        Test.checks([\n          Test.check<typeof result, Expectation, Test.Pass>(),\n        ])\n      });\n    });\n  });\n\n  (function describe(_ = 'Transpose') {\n    (function it(_ = 'should transpose an array') {\n      const input: [\n        [ 1, 2 ],\n        [ 3, 4 ],\n        [ 5, 6 ]\n      ] = [\n        [ 1, 2 ],\n        [ 3, 4 ],\n        [ 5, 6 ]\n        ]\n      \n      type Expectation = [\n        [ 1, 3, 5 ],\n        [ 2, 4, 6 ]\n      ]\n\n      const transposed: Expectation = transpose(input)\n    });\n\n    (function it(_ = 'should transpose an empty array') {\n      const input: [] = []\n\n      type Expectation = []\n\n      const transposed: Expectation = transpose(input)\n    });\n\n    (function it(_ = 'should transpose incomplete array') {\n      const input: [\n        [ 1, 3 ],\n        [ 2,   ]\n      ] = [\n        [ 1, 3 ],\n        [ 2,   ]\n      ]\n\n      type Expectation = [[1], [3]]\n\n      const transposed: Expectation = transpose<typeof input>(input)\n    });\n  });\n})();\n\n//#region Utility function declarations for type testing\n\n// Transpose method converts [x, y] pairs into [xs, ys] array.\ndeclare function transpose<\n  A extends unknown[][]\n>(input: A): Transpose<[ ...A ]>;\n\n//#endregion\n\n// create dummy values with a desired type\nconst input = <T>(): T => 123 as any\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n      \"target\": \"es2015\",\n      \"module\": \"ESNext\",\n      \"moduleResolution\": \"Node\",\n      \"strict\": false,\n      \"noImplicitAny\": true,\n      \"sourceMap\": false,\n      \"noUnusedLocals\": true,\n      \"noUnusedParameters\": true,\n      \"strictNullChecks\": true,\n      \"strictFunctionTypes\": true,\n      \"declaration\": true,\n      \"baseUrl\": \"./src\",\n      \"lib\": [\n        \"dom\",\n        \"es2016\",\n        \"es2017.object\"\n      ],\n      \"outDir\": \"dist\",\n      \"skipLibCheck\": true,\n      \"esModuleInterop\": true\n  },\n  \"include\": [\n    \"src/**/*.ts\"\n  ],\n  \"exclude\": [\n      \"node_modules\",\n      \"**/*.spec.ts\"\n  ]\n}\n"
  }
]