{"id":12245,"library":"typescript-monads","title":"TypeScript Monads","description":"typescript-monads is a JavaScript/TypeScript library that provides common functional programming monads and abstractions to manage control flow and state, aiming to enable cleaner, safer code by reducing null/undefined checks and explicit error handling. It currently stands at version 9.5.0, with minor and patch releases occurring frequently (monthly to quarterly), and major versions released approximately yearly (v9.0.0 in January 2024). Key differentiators include its comprehensive set of monads like Maybe, List, Either, Result, State, and Reader, offering alternatives to traditional imperative logic for handling optional values, collections, error propagation, and side effects in a more declarative and type-safe manner within TypeScript projects. The library emphasizes lazy evaluation for collections and provides robust type definitions for seamless integration into TypeScript applications.","status":"active","version":"9.5.0","language":"javascript","source_language":"en","source_url":"https://github.com/patrickmichalina/typescript-monads","tags":["javascript","typescript","monads","maybe","result","either","list","state"],"install":[{"cmd":"npm install typescript-monads","lang":"bash","label":"npm"},{"cmd":"yarn add typescript-monads","lang":"bash","label":"yarn"},{"cmd":"pnpm add typescript-monads","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for `maybeToObservable` and other RxJS integration methods within the `Maybe` monad. It's an optional peer dependency.","package":"rxjs","optional":true}],"imports":[{"note":"The library primarily targets modern JavaScript environments supporting ESM. While some bundlers might handle CJS `require`, direct usage in Node.js without transpilation should prefer ESM imports. `maybe` is the primary factory function for the Maybe monad.","wrong":"const { maybe } = require('typescript-monads')","symbol":"maybe","correct":"import { maybe } from 'typescript-monads'"},{"note":"List is a named export, not a default export. Incorrectly importing it as a default will result in `undefined`.","wrong":"import List from 'typescript-monads'","symbol":"List","correct":"import { List } from 'typescript-monads'"},{"note":"The `Result` monad itself is exported as a class (`Result`), while factory functions for success/failure are `ok` and `fail` (e.g., `import { ok, fail } from 'typescript-monads'`).","wrong":"import { result } from 'typescript-monads'","symbol":"Result","correct":"import { Result } from 'typescript-monads'"},{"note":"Requires `rxjs` to be installed separately as an optional dependency. If `rxjs` is not present, calling this function will lead to a runtime error.","symbol":"maybeToObservable","correct":"import { maybeToObservable } from 'typescript-monads'"}],"quickstart":{"code":"import { maybe, none, List, ok, fail } from 'typescript-monads';\n\n// Demonstrating Maybe monad for optional values\nfunction getUserDisplayName(user: { firstName?: string, lastName?: string }): string {\n  return maybe(user.firstName)\n    .flatMap(first => maybe(user.lastName).map(last => `${first} ${last}`))\n    .valueOr('Guest');\n}\n\nconsole.log(getUserDisplayName({ firstName: 'Alice', lastName: 'Smith' }));\nconsole.log(getUserDisplayName({ firstName: 'Bob' }));\nconsole.log(getUserDisplayName({}));\n\n// Demonstrating Result monad for error handling\nfunction divide(a: number, b: number): typeof Result<number, string> {\n  if (b === 0) {\n    return fail('Cannot divide by zero');\n  } \n  return ok(a / b);\n}\n\ndivide(10, 2).match({\n  ok: val => console.log(`Result: ${val}`), // Result: 5\n  fail: err => console.error(`Error: ${err}`)\n});\n\ndivide(10, 0).match({\n  ok: val => console.log(`Result: ${val}`),\n  fail: err => console.error(`Error: ${err}`)\n}); // Error: Cannot divide by zero\n\n// Demonstrating List monad for functional collections\nconst numbers = List.of(1, 2, 3, 4, 5);\nconst doubledEvens = numbers\n  .filter(n => n % 2 === 0)\n  .map(n => n * 2)\n  .toArray();\n\nconsole.log(doubledEvens); // [4, 8]\n","lang":"typescript","description":"This quickstart illustrates the core usage of the Maybe, Result, and List monads for handling optional values, errors, and collections functionally. It demonstrates how to create instances, chain operations, and safely extract values or handle error conditions."},"warnings":[{"fix":"Review the specific usage of `Maybe.apply` and update its arguments according to the new signature, as detailed in the v9.0.0 release notes or updated documentation.","message":"The signature of `Maybe.apply` method was changed in v9.0.0. Code using the `apply` method might need adjustments.","severity":"breaking","affected_versions":">=9.0.0"},{"fix":"Install RxJS: `npm install rxjs` or `yarn add rxjs`.","message":"Integration with RxJS features like `maybeToObservable` requires the `rxjs` package to be explicitly installed as a dependency in your project. It is not bundled with `typescript-monads`.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always use provided monadic methods (e.g., `.valueOr(defaultValue)`, `.match({ some: ..., none: ... })`, `.flatMap(fn)`) to safely interact with values that may or may not be present, preventing unexpected runtime errors.","message":"Attempting to access a value from a `None` (for Maybe) or a `Fail` (for Result) directly without using safe methods like `valueOr`, `match`, or `tapSome`/`tapOk` will result in `undefined` or an unhandled value, negating the benefits of the monad.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure strict TypeScript settings are enabled. Pay close attention to the generic types when instantiating monads (e.g., `none<number>()` or `List.empty<string>()`) and verify the return types of functions passed to `map`, `flatMap`, and `filter`.","message":"The library heavily relies on TypeScript type inference. While it provides runtime safety, incorrect type declarations when creating monads or using `flatMap`/`map` can lead to type mismatches that TypeScript might catch but could lead to logical errors if types are asserted incorrectly.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Install RxJS as a dependency: `npm install rxjs` or `yarn add rxjs`.","cause":"The `rxjs` package is not installed, but a function that integrates with RxJS (like `maybeToObservable`) is being called.","error":"TypeError: (0, typescript_monads_1.maybeToObservable) is not a function"},{"fix":"Use `import { ok, fail, Result } from 'typescript-monads'` instead. Factory functions are `ok()` and `fail()`, and the type is `Result<T, E>`.","cause":"Attempting to import `result` (lowercase) as a named export, but the primary factory functions are `ok` and `fail`, and the type is `Result` (uppercase).","error":"TS2305: Module ''typescript-monads'' has no exported member 'result'."},{"fix":"Ensure the script is loaded and executed, and the correct global variable name is used. As per documentation, it exposes `typescriptMonads`. If using modern bundlers, prefer `import` statements.","cause":"The `typescript-monads` script was loaded directly in the browser via `unpkg` without ensuring it exposes a global variable, or it's trying to access `typescriptMonads` before the script fully loads or in a context where it's not exposed.","error":"ReferenceError: typescriptMonads is not defined (in browser)"},{"fix":"Use the provided monadic methods for value extraction or transformation, such as `.valueOr(defaultValue)`, `.match(...)`, `.tapSome(...)`, `.map(...)`, or `.flatMap(...)`.","cause":"Directly trying to access a property like `.value` on a monad instance, which is an incorrect pattern as monads wrap values and require specific methods for safe extraction.","error":"TS2339: Property 'value' does not exist on type 'Maybe<number>' (or 'Result<string, Error>')."}],"ecosystem":"npm"}