{"id":26675332,"url":"https://github.com/rackspace/maybe-result","last_synced_at":"2026-04-25T16:34:05.708Z","repository":{"id":275228644,"uuid":"920708720","full_name":"rackspace/maybe-result","owner":"rackspace","description":"Safe handling of null and undefined in Typescript and Javascript","archived":false,"fork":false,"pushed_at":"2025-04-28T17:05:43.000Z","size":310,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-14T03:30:07.669Z","etag":null,"topics":["fp","functional-programming","maybe","null","optional","typescript","typescript-library","undefined"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rackspace.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-01-22T16:31:06.000Z","updated_at":"2025-04-28T17:05:45.000Z","dependencies_parsed_at":"2025-02-01T01:28:40.573Z","dependency_job_id":"77b1e4ca-b911-449c-8fc6-970f086da3c5","html_url":"https://github.com/rackspace/maybe-result","commit_stats":null,"previous_names":["rackspace/maybe-ts","rackspace/maybe"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/rackspace/maybe-result","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rackspace%2Fmaybe-result","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rackspace%2Fmaybe-result/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rackspace%2Fmaybe-result/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rackspace%2Fmaybe-result/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rackspace","download_url":"https://codeload.github.com/rackspace/maybe-result/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rackspace%2Fmaybe-result/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32269462,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-25T09:15:33.318Z","status":"ssl_error","status_checked_at":"2026-04-25T09:15:31.997Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fp","functional-programming","maybe","null","optional","typescript","typescript-library","undefined"],"created_at":"2025-03-26T03:17:42.312Z","updated_at":"2026-04-25T16:34:05.690Z","avatar_url":"https://github.com/rackspace.png","language":"TypeScript","readme":"# maybe-result - Safe function return handling in Typescript and Javascript\n\nDeciding when a function should return `undefined`, throw an `Error`, or return some other indicator that\n\"something isn't right\" is tough. We don't always know how users _calling_ our function\nwill use it, and we want to be clear, clean, and safe.\n\nThis library provides two approaches for wrapping function results:\n\n- [Maybe](#maybe) for when something may or may not exist. (Jump to [API](#maybe-api))\n- [Result](#result) for when you might have an error, but want to let the caller decide how to handle it. (Jump to [API](#result-api))\n\nJump to [Learn More](#learn-more) section - Jump to [Origins and Alternatives](#origin-and-alternatives) section\n\n## Maybe\n\nIn many languages, we have concepts of exceptions and `null` values.\n(JavaScript has both `null` and `undefined`. Ugh!)\n\nOften a function will need to indicate when a value _maybe_ exists, or it does not.\nIn JavaScript, the \"does not\" is usually returned as `undefined` or `null`, but sometimes\na function will _throw_ an `Error` type instead. Thus, the developer needs to figure out\nhow that particular function behaves and adapt to that if they want to handle\nthe missing value.\n\nFinally, throwing Errors in TypeScript can be expensive, as a stack trace must be\ngenerated and cross-referenced to the `.js.map` files. These stack traces to your\nTypeScript source are immensely useful for tracing actual errors, but they are wasted\nprocessing when ignored.\n\nThe `Maybe` type makes this cleaner. Elm was an early language that defined this.\nRust has an `Option` type, which is the same concept.\n\nA `Maybe` is a wrapper object that contains either \"some\" value, or \"none\".\nA function can thus return a `Maybe`, and the client can then _choose_ how to handle\nthe possibly missing value. The caller can explicitly check for `isValue` or\n`isNone`, or can simply `unwrap` the `Maybe` and let it throw an error if \"none\".\nIt is now the caller's choice. There are many other helper functions too, such as\nto unwrap with a default value to return in place of throwing if `isNone`.\n\nIn JavaScript we like to throw `Error` types, but in other languages we call these _exceptions_.\n**Throwing is still good for _exceptional_ cases. `Maybe` is for \"normal\" control flows.**\n\n`Maybe` is not only for function return values. It may be used elsewhere where you want a type-safe\nand immutable alternative to `undefined` and `null`.\n\nHere's a nice introduction to the concept:\n[Implementing a Maybe Pattern using a TypeScript Type Guard](https://medium.com/@sitapati/implementing-a-maybe-pattern-using-a-typescript-type-guard-81b55efc0af0)\n\n### Example by Story\n\nYou might define a data repository class (access to a data store) like this:\n\n```ts\nclass WidgetRepository {\n  get(widgetID: string): Promise\u003cWidget\u003e {\n    // implementation ...\n  }\n}\n```\n\nIf the Widget isn't found, you throw a `NotFoundError`. All is well until you start _expecting_\na Widget not to be found. That becomes valid flow, so you find yourself writing this a lot:\n\n```ts\nlet widget: Widget | undefined;\ntry {\n  widget = await widgetRepo.get(widgetID);\n} catch (error) {\n  if (!(error instanceof NotFoundError)) {\n    throw error;\n  }\n}\n\nif (widget) {\n  /* ... */\n}\n```\n\nYou may be willing to do that once... but not more. So you first try to change the repository:\n\n```ts\nclass WidgetRepository {\n  get(widgetID: string): Promise\u003cWidget | undefined\u003e {\n    // implementation ...\n  }\n}\n```\n\nNow it returns `undefined` instead of throwing. Oh, but what a hassle - now you have to _check_ for\n`undefined` _every time_ you call the function! So instead, you define _two_ functions:\n\n```ts\nclass WidgetRepository {\n  getOrThrow(widgetID: string): Promise\u003cWidget\u003e {\n    // implementation ...\n  }\n  getIfFound(widgetID: string): Promise\u003cWidget | undefined\u003e {\n    // implementation ...\n  }\n}\n```\n\nThat makes it easier. It works. You just have to write _two_ functions every time you write a get function. 🙄\n\n**OR...** use `Maybe` 🎉\n\n```ts\nclass WidgetRepository {\n  async get(widgetID: string): PromiseMaybe\u003cWidget\u003e {\n    // implementation ...\n  }\n}\n\n// One place elsewhere where you want to throw if not found\nconst widget = Maybe.unwrap(await widgetRepo.get(widgetID));\n\n// Another place elsewhere where you want to handle the mising lookup\nconst widget = Maybe.unwrapOrNull(await widgetRepo.get(widgetID));\nif (widget) {\n  // do work\n} else {\n  // do other work\n}\n\n// Someplace where you have a default\nconst widget = (await widgetRepo.get(widgetID)).unwrapOr(defaultWidget);\n```\n\n### Maybe API\n\nThere are many functions, both on the `Maybe` instance and as static helper functions in\nthe `Maybe` namespace:\n\n```ts\ninterface Maybe\u003cT\u003e extends Iterable\u003cT extends Iterable\u003cinfer U\u003e ? U : never\u003e {\n  /** `true` when this has \"some\" value. */\n  readonly isValue: boolean;\n  /** `false` when this is \"none\". */\n  readonly isNone: boolean;\n  /**\n   * Helper function if you know you have a `Maybe\u003cT\u003e` and `T` is iterable.\n   * @returns value's iterator or an iterator that is immediately done, if value is not iterable.\n   */\n  [Symbol.iterator](): Iterator\u003cT extends Iterable\u003cinfer U\u003e ? U : never\u003e;\n  /**\n   * Returns the \"some\" value, or throw.\n   * Use if you want a \"none\" value to throw an error.\n   *\n   * @returns the \"some\" value\n   * @throws NoneError when \"none\".\n   */\n  unwrap(): T;\n  /**\n   * Unwrap the \"some\" value and return it,\n   * or when \"none\" returns the given alternative instead.\n   *\n   * @param altValue value to return when \"none\"\n   * @returns the \"some\" value, or `altValue` when \"none\"\n   */\n  unwrapOr\u003cT2\u003e(altValue: T2): T | T2;\n  /**\n   * Unwrap the \"some\" value and return it,\n   * or-else when \"none\" returns the given alternative lazy callback instead.\n   *\n   * @param altValueFn lazy callback result to return when \"none\"\n   * @returns the \"some\" value, or the `altValueFn` result when \"none\"\n   */\n  unwrapOrElse\u003cT2\u003e(altValueFn: () =\u003e T2): T | T2;\n  /**\n   * Returns the \"some\" value or `null` instead of throwing an error if \"none\".\n   *\n   * @returns the \"some\" value, or `null` when \"none\"\n   */\n  unwrapOrNull(): T | null;\n  /**\n   * Returns the \"some\" value, if exists. Throws when \"none\".\n   *\n   * @param altError (optional) `Error`, message for an `Error`, or callback that produces an `Error` to throw when \"none\"\n   * @returns the \"some\" value\n   * @throws the `altError` or `NoneError` when \"none\".\n   */\n  unwrapOrThrow\u003cE extends Error\u003e(altError?: string | Error | (() =\u003e E)): T;\n  /**\n   * Assert that this `Maybe` has \"some\" value.\n   * Throw with provided message (or a default) when not \"some\" value.\n   * Generally you should use an unwrap function instead, but this is useful for unit testing.\n   *\n   * @param message the message to throw when this is \"none\"\n   * @returns the \"some\" value\n   * @throws `new NoneError(message)` when is \"none\"\n   */\n  assertIsValue(message?: string): T;\n  /**\n   * Assert that this `Maybe` is \"none\".\n   * Throw with provided message (or a default) when not \"none\".\n   * Generally, prefer to handle the \"none\" case explicitly or with `unwrapOr` or `unwrapOrNull`.\n   * This may be useful for unit testing.\n   *\n   * @param message the message to throw when \"some\".\n   * @returns the \"none\"\n   * @throws `new Error(msg,value)` when \"some\"\n   */\n  assertIsNone(message?: string): Maybe.None;\n  /**\n   * Perform boolean \"or\" operation.\n   *\n   * Returns `this` when \"some\", otherwise returns `other`.\n   *\n   * @param other the right-hand operator\n   * @returns \"none\" or `other`.\n   */\n  or\u003cT2\u003e(other: Maybe\u003cT2\u003e): Maybe\u003cT\u003e | Maybe\u003cT2\u003e;\n  /**\n   * Perform a lazy boolean \"or\" operation.\n   *\n   * Returns `this` when \"some\", or-else returns the `otherFn` callback result.\n   *\n   * @param otherFn the right-hand operator\n   * @returns \"none\" or `otherFn` result.\n   */\n  orElse\u003cT2\u003e(otherFn: () =\u003e Maybe\u003cT2\u003e): Maybe\u003cT\u003e | Maybe\u003cT2\u003e;\n  /**\n   * Perform boolean \"and\" operation.\n   *\n   * Returns \"none\" if this is \"none\", otherwise returns `other`.\n   *\n   * @param other the right-hand operator\n   * @returns \"none\" or `other`.\n   */\n  and\u003cT2\u003e(other: Maybe\u003cT2\u003e): Maybe\u003cT2\u003e | Maybe.None;\n  /**\n   * Perform a lazy boolean \"and\" operation by\n   * chaining a \"some\" value into a mapper function.\n   *\n   * Calls `mapperFn` when \"some\" value,\n   * otherwise returns itself as still \"none\" without calling `mapperFn`.\n   *\n   * @param mapperFn function to map this value to another `Maybe`. (See `.map` to map values instead.)\n   * @returns mapped \"some\" value, or `this` when \"none\".\n   */\n  andThen\u003cT2\u003e(mapperFn: (value: T) =\u003e Maybe\u003cT2\u003e): Maybe\u003cT2\u003e | Maybe.None;\n  /**\n   * Transform \"some\" value, when present.\n   *\n   * Maps an `Maybe\u003cT\u003e` to `Maybe\u003cU\u003e` by applying a function to the \"some\" value,\n   * leaving a \"none\" untouched.\n   *\n   * This function can be used to compose the `Maybe` of two functions.\n   *\n   * @param mapperFn function to map this value to a new value.\n   *                 (See `.andThen` to map to a new `Maybe` instead.)\n   * @returns a new `Maybe` with the mapped \"some\" value, or `this` when \"none\"\n   */\n  map\u003cU\u003e(mapperFn: (value: T) =\u003e U): Maybe\u003cU\u003e;\n  /**\n   * Transform \"some\" value or use an alternative, resulting in a Maybe that is always \"some\" value.\n   *\n   * Maps a `Maybe\u003cT\u003e` to `Maybe\u003cU\u003e` by either converting `T` to `U` using `mapperFn` (in case\n   * of \"some\") or using the `altValue` value (in case of \"none\").\n   *\n   * If `altValue` is a result of a function call consider using `mapOrElse` instead, it will\n   * only evaluate the function when needed.\n   *\n   * @param mapperFn function to map this \"some\" value to a new value.\n   * @param altValue value to return when \"none\"\n   * @returns a new `Maybe` with the mapped \"okay\" value or the `altValue` value\n   */\n  mapOr\u003cU\u003e(mapperFn: (value: T) =\u003e U, altValue: U): MaybeValue\u003cU\u003e;\n  /**\n   * Transform \"some\" value or-else lazy call an alternative, resulting in a Maybe that is always \"some\" value.\n\n   * Maps a `Maybe\u003cT\u003e` to `Maybe\u003cU\u003e` by either converting `T` to `U` using `mapperFn` (in case\n   * of \"some\") or using the `altValueFn` callback value (in case of \"none\").\n   *\n   * @param mapperFn function to map this \"some\" value to a new value.\n   * @param altValueFn callback result to return when \"none\"\n   * @returns a new `Maybe` with the mapped \"okay\" value or the alternative result value\n   */\n  mapOrElse\u003cU\u003e(mapperFn: (value: T) =\u003e U, altValueFn: () =\u003e U): MaybeValue\u003cU\u003e;\n  /**\n   * Filters \"some\" value to \"none\" if `predicateFn` returns `false`.\n   *\n   * When \"some\", calls the `predicateFn` and if it returns `false` returns \"none\".\n   * When \"none\", returns `this` unchanged and predicate not called.\n   *\n   * @param predicateFn filter function indicating whether to keep (`true`) the value\n   * @returns this `Maybe` or `Maybe.None`.\n   */\n  filter(predicateFn: (value: T) =\u003e boolean): Maybe\u003cT\u003e;\n  /**\n   * Convert a `Maybe\u003cT\u003e` to a `Result\u003cT, E\u003e`, with the provided `Error` value\n   * to use when this is \"none\".\n   *\n   * @param error to use when \"none\"; defaults to a `NoneError`\n   * @return a `Result` with this \"some\" as the \"okay\" value, or `error` as the \"error\".\n   */\n  toResult\u003cE\u003e(error?: E): Result\u003cT, E | NoneError\u003e;\n  /**\n   * This `Maybe` as a loggable string.\n   * @returns string describing this `Maybe`\n   */\n  toString(): string;\n}\n\n/** A `Promise` to a `Maybe` */\ntype PromiseMaybe\u003cT\u003e = Promise\u003cMaybe\u003cT\u003e\u003e;\n\ndeclare namespace Maybe {\n  /** Generic None result of a Maybe */\n  const None: MaybeNone;\n  type None = MaybeNone;\n\n  /** A Successful Maybe result that just doesn't have any value */\n  const Empty: MaybeValue\u003cvoid\u003e;\n  type Empty = MaybeValue\u003cvoid\u003e;\n\n  /** Factory create a `Maybe` with \"some\" value */\n  const withValue: \u003cT\u003e(value: T) =\u003e MaybeValue\u003cT\u003e;\n  /**\n   * Factory create a `Maybe` of \"none\" with context of \"what\" was not found.\n   * @param what string(s) describing what wasn't found\n   */\n  const notFound: (...what: string[]) =\u003e MaybeNotFound;\n  /**\n   * Factory create a `Maybe` with a \"none\" result. You can use the `Maybe.None` singleton directly;\n   * this just provides synchronicity with the other factory functions.\n   */\n  const asNone: () =\u003e MaybeNone;\n  /**\n   * Factory create a `Maybe` with success but no actual value (`void`).\n   * You can use the Empty singleton directly instead;\n   * this just provides synchronicity with the other factory functions.\n   */\n  const empty: () =\u003e MaybeValue\u003cvoid\u003e;\n  /**\n   * Helper to wrap a value as a `Maybe`.\n   *\n   * @param value a value, undefined, or null\n   * @return a `Maybe`: \"none\" if `undefined` or `null`, otherwise \"some\" value.\n   */\n  const wrap: \u003cT\u003e(\n    value: T | undefined | null,\n  ) =\u003e MaybeNone | MaybeValue\u003cNonNullable\u003cT\u003e\u003e;\n  /**\n   * Returns the value contained in `maybe`, or throws if \"none\".\n   * Same as `maybe.unwrap()`, but more readable when `maybe` is returned from an async\n   * function: `Maybe.unwrap(await repository.get(id))`\n   *\n   * @param maybe to unwrap\n   * @return the \"some\" value\n   * @throws NoneError if `maybe` is \"none\".\n   */\n  const unwrap: \u003cT\u003e(maybe: Maybe\u003cT\u003e) =\u003e T;\n  /**\n   * Returns the \"some\" value in `maybe`, or `null` if \"none\".\n   * Same as `maybe.unwrapOrNull()`, but more readable when `maybe` is returned from an\n   * async function: `Maybe.unwrapOrNull(await repository.get(id))`\n   *\n   * @param maybe to unwrap\n   * @return the \"some\" value or `null`\n   */\n  const unwrapOrNull: \u003cT\u003e(maybe: Maybe\u003cT\u003e) =\u003e T | null;\n  /**\n   * Parse a set of `maybes`, returning an array of all \"some\" values.\n   * Short circuits with the first \"none\" found, if any\n   *\n   * @param maybes list to check\n   * @return array of \"some\" values or `Maybe.None`.\n   */\n  function allOrNone\u003cT extends Maybe\u003cany\u003e[]\u003e(\n    ...maybes: T\n  ): Maybe\u003cMaybeValueTypes\u003cT\u003e\u003e;\n  /**\n   * Parse a set of `maybes`, returning an array of all \"some\" values,\n   * filtering out any \"none\"s found, if any.\n   *\n   * @param maybes list to check\n   * @return array of some\" values\n   */\n  function allValues\u003cT\u003e(...maybes: Maybe\u003cT\u003e[]): T[];\n  /**\n   * Parse a set of `maybes`, short-circuits when an input value is \"some\".\n   * If no \"some\" is found, returns a \"none\".\n   * @param maybes list to check\n   * @return the first \"some\" value given, or otherwise \"none\".\n   */\n  function any\u003cT extends Maybe\u003cany\u003e[]\u003e(\n    ...maybes: T\n  ): Maybe\u003cMaybeValueTypes\u003cT\u003e[number]\u003e;\n  /**\n   * Type-guard to identify and narrow a `Maybe`\n   */\n  function isMaybe\u003cT\u003e(value: unknown): value is Maybe\u003cT\u003e;\n}\n\n/**\n * A special form of Maybe's \"none\" value with additional context.\n */\ndeclare class MaybeNotFound extends MaybeNone {\n  private readonly what;\n  /**\n   * Construct a `Maybe` \"none\" that indicates a \"what\" wasn't found.\n   * @param what texts describing \"what\" wasn't found.\n   */\n  constructor(what: string[]);\n  unwrap(): never;\n}\n\n/** HTTP-friendly `Error` that is thrown when unwrapping a `MaybeNotFound` */\ndeclare class NotFoundError extends Error {\n  /** Property use by some HTTP servers */\n  readonly status: 404;\n  /** Property use by some HTTP servers */\n  readonly statusCode: 404;\n  constructor(msg: string);\n}\n```\n\n## Result\n\nUnlike `Maybe`, which simply has some value or no value and doesn't want to return `undefined`,\n`Result` is for when you have an **error** and don't want to `throw`.\nSimilar to `Maybe`, this is all about the function giving the caller the _choice_ of\nhow to handle a situation - in this case an _exceptional_ situation.\n\nThis is modeled off of the Rust `Result` type, but made to pair cleanly with this\nimplementation of `Maybe`.\n\n### Example\n\nExpanding on the previous example of a `WidgetRepository`,\nlet's add a function in the repository that creates a new widget.\nA `create` function should error out if the assumption that the\nwidget doesn't yet exist is false.\n\n```ts\nclass WidgetRepository {\n  async create(\n    widget: CreatableWidget,\n  ): Promise\u003cResult\u003cWidget, ConstraintError\u003e\u003e {\n    try {\n      // implementation ...\n      return Result.okay(newWidget);\n    } catch (err) {\n      return Result.error(err);\n    }\n  }\n}\n\n/*\n * Elsewhere in the create-widget use-case...\n */\nconst createResult = await widgetRepo.create(creatableWidget);\n\nif (createResult.isOkay) {\n  return createResult.value;\n} else {\n  // Throw more end-user aligned error instead of the database error\n  throw new HttpBadRequest(\"Widget already exists\");\n}\n\n/*\n * Or more simply...\n */\nconst createResult = await widgetRepo.create(creatableWidget);\nreturn createResult.unwrapOrThrow(new HttpBadRequest(\"Widget already exists\"));\n\n/*\n * Or if you just want the behavior of if Result wasn't used, just unwrap it\n * and any contained error will throw.\n */\nreturn (await widgetRepo.create(creatableWidget)).unwrap();\n// or slightly more readable:\nreturn Result.unwrap(await widgetRepo.create(creatableWidget));\n// or convert to a Maybe, so that Maybe.None is returned in place of the error\nreturn (await widgetRepo.create(creatableWidget)).toMaybe();\n```\n\n### Result API\n\nThere are many functions, both on the `Result` instance and as static helper functions in\nthe `Result` namespace:\n\n```ts\ninterface Result\u003cT, E\u003e\n  extends Iterable\u003cT extends Iterable\u003cinfer U\u003e ? U : never\u003e {\n  /** `true` when this contains an \"okay\" value */\n  readonly isOkay: boolean;\n  /** `true` when this contains an \"error\" value */\n  readonly isError: boolean;\n  /**\n   * Helper function if you know you have a Result\u003cT\u003e and T is iterable\n   * @returns iterator over the okay value\n   */\n  [Symbol.iterator](): Iterator\u003cT extends Iterable\u003cinfer U\u003e ? U : never\u003e;\n  /**\n   * Unwrap the result's \"okay\" value and return it.\n   * When \"error\", throws the value instead.\n   * Generally, prefer to handle the error case explicitly or with `unwrapOr` or `unwrapOrNull`.\n   *\n   * @returns the \"okay\" value\n   * @throws the \"error\" value\n   */\n  unwrap(): T;\n  /**\n   * Unwrap the result's \"okay\" value and return it,\n   * or when \"error\", returns given alternative instead.\n   *\n   * @param altValue value or callback result to return when \"error\"\n   * @returns the \"okay\" value or the `altValue`.\n   */\n  unwrapOr\u003cT2\u003e(altValue: T2): T | T2;\n  /**\n   * Unwrap the result's \"okay\" value and return it,\n   * or-else when \"error\" calls alternative lazy callback and returns that value.\n   *\n   * @param altValueFn value or callback result to return when \"error\"\n   * @returns the \"okay\" value or the `altValueFn` result when \"error\".\n   */\n  unwrapOrElse\u003cT2\u003e(altValueFn: (error: E) =\u003e T2): T | T2;\n  /**\n   * Unwrap the result's \"okay\" value and return it.\n   * When \"error\", returns `null`.\n   *\n   * @returns the \"okay\" value or `null`\n   */\n  unwrapOrNull(): T | null;\n  /**\n   * Unwrap the result's \"okay\" value and return it.\n   * otherwise if an `altError` is provided, it is thrown,\n   * otherwise the \"error\" value of this result is thrown.\n   *\n   * When no `altError` parameter is provided, this is the same as `.unwrap()`\n   * but a bit more descriptive.\n   *\n   * @param altError (optional) `Error`, message for an `Error`, or callback that produces an `Error` to throw when \"error\"\n   * @returns \"okay\" value\n   * @throws `altError` or the result \"error\" value\n   */\n  unwrapOrThrow\u003cE2 extends Error\u003e(\n    altError?: string | Error | ((error: E) =\u003e E2),\n  ): T;\n  /**\n   * Assert that this `Result` is \"okay\".\n   * Throw with provided message (or a default) when not \"okay\".\n   * Generally you should use an unwrap function instead, but this is useful for unit testing.\n   *\n   * @param message the message to throw when this is an \"error\"\n   * @returns the value when this is \"okay\"\n   * @throws `new Error(message,value)` when is \"error\"\n   */\n  assertIsOkay(message?: string): T;\n  /**\n   * Assert that this `Result` is \"error\".\n   * Throw with provided message (or a default) when not \"error\".\n   * Generally, prefer to handle the \"error\" case explicitly or with `unwrapOr` or `unwrapOrNull`.\n   * This may be useful for unit testing.\n   *\n   * @param message the message to throw when \"okay\".\n   * @returns the value when \"error\"\n   * @throws `new Error(msg,value)` when \"okay\"\n   */\n  assertIsError(message?: string): E;\n  /**\n   * Perform boolean \"or\" operation.\n   *\n   * Returns `this` when \"okay\", otherwise returns `other`.\n   *\n   * @param other the right-hand operator\n   * @returns this \"okay\" or `other`.\n   */\n  or\u003cT2, E2\u003e(other: Result\u003cT2, E2\u003e): OkayResult\u003cT\u003e | Result\u003cT2, E2\u003e;\n  /**\n   * Perform a lazy boolean \"or\" operation.\n   *\n   * Returns `this` when \"okay\", or-else lazy-cals `otherFn` and returns its result.\n   *\n   * @param otherFn the right-hand operator\n   * @returns this \"okay\" or `otherFn` result.\n   */\n  orElse\u003cT2\u003e(otherFn: (error: E) =\u003e OkayResult\u003cT2\u003e): OkayResult\u003cT | T2\u003e;\n  orElse\u003cE2\u003e(otherFn: (error: E) =\u003e ErrorResult\u003cE2\u003e): Result\u003cT, E2\u003e;\n  orElse\u003cT2, E2\u003e(otherFn: (error: E) =\u003e Result\u003cT2, E2\u003e): Result\u003cT | T2, E2\u003e;\n  /**\n   * Perform boolean \"and\" operation.\n   *\n   * When \"error\", returns this \"error\",\n   * otherwise returns `other`.\n   *\n   * @param other the right-hand operator\n   * @returns this \"error\" or `other`.\n   */\n  and\u003cT2, E2\u003e(other: Result\u003cT2, E2\u003e): ErrorResult\u003cE\u003e | Result\u003cT2, E2\u003e;\n  /**\n   * Perform a lazy boolean \"and\" operation by\n   * chaining the \"okay\" value into a mapper function.\n   *\n   * Lazy calls `mapperFn` if the result \"okay\",\n   * otherwise returns this \"error\" `Result` as-is without calling `mapperFn`.\n   *\n   * This function can be used for control flow based on `Result` values.\n   *\n   * @param mapperFn function to map this value to another `Result`. (See `.map` to map values instead.)\n   * @returns mapped \"okay\" `Result` or `this` when \"error\"\n   */\n  andThen\u003cT2\u003e(mapperFn: (value: T) =\u003e OkayResult\u003cT2\u003e): Result\u003cT2, E\u003e;\n  andThen\u003cE2\u003e(mapperFn: (value: T) =\u003e ErrorResult\u003cE2\u003e): Result\u003cT, E | E2\u003e;\n  andThen\u003cT2, E2\u003e(mapperFn: (value: T) =\u003e Result\u003cT2, E2\u003e): Result\u003cT2, E | E2\u003e;\n  /**\n   * Transform \"okay\" value, when present.\n   *\n   * Maps a `Result\u003cT, E\u003e` to `Result\u003cU, E\u003e` by applying a function to the \"okay\" value,\n   * leaving an \"error\" value unchanged.\n   *\n   * This function can be used to compose the results of two functions.\n   *\n   * @param mapperFn function to map this value to a new value.\n   *                 (See `.andThen` to map to a new `Result` instead.)\n   * @returns a new `Result` with the mapped \"okay\" value, or `this` when \"error\"\n   */\n  map\u003cU\u003e(mapperFn: (value: T) =\u003e U): Result\u003cU, E\u003e;\n  /**\n   * Transform \"okay\" value or use an alternative, resulting in a `Result` that is always \"okay\".\n   *\n   * Maps a `Result\u003cT, E\u003e` to `Result\u003cU, E\u003e` when \"okay\" by applying a function.\n   * When \"error\", returns given alternative instead.\n   *\n   * @param mapperFn function to map this value to a new value.\n   * @param altValue value to return when \"error\"\n   * @returns a new `Result` with the mapped \"okay\" value or the `altValue` value\n   */\n  mapOr\u003cU\u003e(mapperFn: (value: T) =\u003e U, altValue: U): OkayResult\u003cU\u003e;\n  /**\n   * Transform \"okay\" value or-else lazy call an alternative, resulting in a `Result` that is always \"okay\".\n   *\n   * Maps a `Result\u003cT, E\u003e` to `Result\u003cU, E\u003e` when \"okay\" by applying a function.\n   * When \"error\", returns value from alternative callback instead.\n   *\n   * @param mapperFn function to map this value to a new value.\n   * @param altValueFn callback result to return when \"error\"\n   * @returns a new `Result` with the mapped \"okay\" value or the alternative value\n   */\n  mapOrElse\u003cU\u003e(\n    mapperFn: (value: T) =\u003e U,\n    altValueFn: (error: E) =\u003e U,\n  ): OkayResult\u003cU\u003e;\n  /**\n   * Transform \"error\" value, when present.\n   *\n   * Maps a `Result\u003cT, E\u003e` to `Result\u003cT, F\u003e` by applying a function to an \"error\" value,\n   * leaving an \"okay\" value unchanged.\n   *\n   * This function can be used to pass through a successful result while handling an error.\n   *\n   * @param mapperFn function to map this \"error\" value to a new error\n   * @returns a new `Result` with the mapped error, or `this` when \"okay\"\n   */\n  mapError\u003cF\u003e(mapperFn: (error: E) =\u003e F): Result\u003cT, F\u003e;\n  /**\n   * Converts this `Result\u003cT, E\u003e` to `Maybe\u003cT\u003e`,\n   * discarding any error details in place of a simple `Maybe.None`.\n   * @returns the \"okay\" value as a `Maybe`, or `Maybe.None` when \"error\"\n   */\n  toMaybe(): Maybe\u003cT\u003e;\n  /**\n   * This `Result` as a loggable string.\n   * @returns string describing this `Result`\n   */\n  toString(): string;\n}\n\n/** A `Promise` to a `Result` */\ntype PromiseResult\u003cT, E\u003e = Promise\u003cResult\u003cT, E\u003e\u003e;\n\ndeclare namespace Result {\n  /** A reusable okay result with no (undefined) value */\n  const OkayVoid: OkayResult\u003cvoid\u003e;\n  /** Factory to create an \"okay\" result */\n  const okay: \u003cT\u003e(value: T) =\u003e OkayResult\u003cT\u003e;\n  /** Factory to create an \"okay\" result with no (undefined) value */\n  const okayVoid: () =\u003e OkayResult\u003cvoid\u003e;\n  /** Factory to create an \"error\" result */\n  const error: \u003cE\u003e(error: E) =\u003e ErrorResult\u003cE\u003e;\n\n  /**\n   * Parse a set of `Result`s, returning an array of all \"okay\" values.\n   * Short circuits to return the first \"error\" found, if any.\n   *\n   * @param results array of results; possibly a mix of \"okay\"s and \"error\"s\n   * @return a single `Result` with the first \"error\" or an \"okay\" value as an array of all the \"okay\" values.\n   */\n  function all\u003cT extends Result\u003cany, any\u003e[]\u003e(\n    ...results: T\n  ): Result\u003cOkayResultTypes\u003cT\u003e, ErrorResultTypes\u003cT\u003e[number]\u003e;\n  /**\n   * Parse a set of `Result`s and returns the first input value that \"okay\".\n   * If no \"okay\" is found, returns an \"error\" result with the error values.\n   *\n   * @param results array of results; possibly a mix of \"okay\"s and \"error\"s\n   * @return a single `Result` with the first \"okay\" or an \"error\" value as an array of all the \"error\" values.\n   */\n  function any\u003cT extends Result\u003cany, any\u003e[]\u003e(\n    ...results: T\n  ): Result\u003cOkayResultTypes\u003cT\u003e[number], ErrorResultTypes\u003cT\u003e\u003e;\n  /**\n   * Returns the value contained in `result`, or throws the \"error\" in `result`.\n   *\n   * Same as `result.unwrap()`, but more reads nicer when `Result` is returned from an async\n   * function: `Result.unwrap(await repository.create(widget))`\n   *\n   * @param result to unwrap\n   * @throws if the result is \"error\"\n   */\n  const unwrap: \u003cT, E\u003e(result: Result\u003cT, E\u003e) =\u003e T;\n  /**\n   * Wrap an operation that may throw and capture it into a `Result`.\n   *\n   * @param opFn the operation function\n   * @return a `Result` with the function output - either \"okay\" or a caught \"error\".\n   */\n  function wrap\u003cT, E = unknown\u003e(opFn: () =\u003e T): Result\u003cT, E\u003e;\n  /**\n   * Wrap an operation that may throw and capture it into a `Result`.\n   *\n   * @param opFn the operation function\n   * @return a `Result` with the function output - either \"okay\" or a caught \"error\".\n   */\n  function wrapAsync\u003cT, E = unknown\u003e(\n    opFn: () =\u003e Promise\u003cT\u003e,\n  ): PromiseResult\u003cT, E\u003e;\n  /**\n   * Type guard to identify and narrow a `Result`\n   */\n  function isResult\u003cT = any, E = any\u003e(val: unknown): val is Result\u003cT, E\u003e;\n}\n```\n\n## Learn More\n\n- View the [Generated API Documentation](https://www.jsdocs.io/package/maybe-result)\n- Read full-coverage examples in the [Maybe unit test suite](src/maybe.spec.ts) and [Result unit test suite](src/result.spec.ts).\n- Functions are named per some foundational concepts:\n  - `wrap` wraps up a value\n  - `unwrap` means to extract the value\n  - `or` performs a boolean _or_ operation between two instances\n  - `orElse` lazily gets the second operand for an _or_ operation via a callback function _only_ if needed\n  - `and` performs a boolean _and_ operation between two instances\n  - `andThen` lazily gets the second operand for an _and_ operation via a callback function _only_ if needed\n  - `map` functions transform the value to return a new instance (immutably)\n\n## Origin and Alternatives\n\nThis implementation is based on [ts-results](https://github.com/vultix/ts-results),\nwhich adheres to the Rust API.\nThis library has more natual word choices, Promise support, additional functions, and other enhancements.\n\nThere are many other libraries that do this same thing - just\n[search NPM for \"maybe\"](https://www.npmjs.com/search?q=maybe).\nIt is up to you to decide which option is best for your project.\n\n_The goal of this library is to be featureful, safe, and easy to understand without\na study of functional programming._\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frackspace%2Fmaybe-result","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frackspace%2Fmaybe-result","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frackspace%2Fmaybe-result/lists"}