{"id":15439825,"url":"https://github.com/bcherny/tsoption","last_synced_at":"2025-04-15T11:54:02.652Z","repository":{"id":57381763,"uuid":"96588581","full_name":"bcherny/tsoption","owner":"bcherny","description":"Correct, easy to use Option type for TypeScript. 🦄","archived":false,"fork":false,"pushed_at":"2019-12-25T12:34:15.000Z","size":94,"stargazers_count":55,"open_issues_count":2,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-17T03:03:29.366Z","etag":null,"topics":["functional-programming","monad","scala","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bcherny.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-07-08T01:35:48.000Z","updated_at":"2024-02-29T05:25:25.000Z","dependencies_parsed_at":"2022-09-14T18:02:13.109Z","dependency_job_id":null,"html_url":"https://github.com/bcherny/tsoption","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcherny%2Ftsoption","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcherny%2Ftsoption/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcherny%2Ftsoption/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bcherny%2Ftsoption/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bcherny","download_url":"https://codeload.github.com/bcherny/tsoption/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249067767,"owners_count":21207395,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["functional-programming","monad","scala","typescript"],"created_at":"2024-10-01T19:09:48.434Z","updated_at":"2025-04-15T11:54:02.634Z","avatar_url":"https://github.com/bcherny.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tsoption [![Build Status][build]](https://circleci.com/gh/bcherny/tsoption) [![npm]](https://www.npmjs.com/package/tsoption) [![mit]](https://opensource.org/licenses/MIT) [![fantasy]](https://github.com/fantasyland/fantasy-land#monad)\n\n[build]: https://img.shields.io/circleci/project/bcherny/tsoption.svg?branch=master\u0026style=flat-square\n[npm]: https://img.shields.io/npm/v/tsoption.svg?style=flat-square\n[mit]: https://img.shields.io/npm/l/tsoption.svg?style=flat-square\n[fantasy]: https://img.shields.io/badge/fantasyland-Monad-ff4ba4.svg?style=flat-square\n\n\u003e Correct, easy to use Option type for TypeScript. Like Scala options; see the [introductory blog post](https://performancejs.com/post/ewff3hj/Options-in-TypeScript).\n\n## Installation\n\n```sh\n# Using Yarn:\nyarn add tsoption\n\n# Or, using NPM:\nnpm install tsoption --save\n```\n\n## Usage\n\n*Note: You can use JavaScript instead of TypeScript, but it's not as fun.*\n\n```ts\nlet a = Option.of(3)                  // Some\u003cnumber\u003e(3)\n  .flatMap(_ =\u003e Some.of(5))           // Some\u003cnumber\u003e(5)\n  .map(_ =\u003e 'a')                      // Some\u003cstring\u003e('a')\n  .orElse(Option.of('b'))             // Some\u003cstring\u003e('a')   (non-string type gives a compile error)\n  .getOrElse('c')                     // 'a'\n\nlet b = Option.of('a')                // Some\u003cstring\u003e('a')\n  .flatMap(_ =\u003e new None)             // None\u003cstring\u003e()      (flatMap can map to any type)\n  .orElse(Option.of('b'))             // Some\u003cstring\u003e('b')   (non-string type gives a compile error)\n  .get()                              // 'b'\n```\n\n## API\n\n*Note: The types of each of the expressions below are known at compile time.*\n\n```ts\n// Create an option\nOption.of(3)                            // Some(3)\nOption.of('abc')                        // Some('abc')\nOption.of(null)                         // None                (for convenience)\nOption.of(undefined)                    // None                (for convenience)\nSome.of(3)                              // Some(3)\nSome.of(null)                           // Some(null)\nnew Some([1, 2, 3])                     // Some([1, 2, 3])\nnew None                                // None\n\n// #flatMap\nSome.of(3).flatMap(_ =\u003e Some.of(_ * 2)) // Some(6)\nNone.of().flatMap(() =\u003e Some.of(2))     // None\n\n// #get\nSome.of(3).get()                        // 3\nNone.of().get()                         // COMPILE ERROR! Can't call get() on None\n\n// #getOrElse\nSome.of(1).getOrElse(2)                 // 1\nNone.of().getOrElse(2)                  // 2\n\n// #isEmpty\nSome.of(2).isEmpty()                    // false (known at compile time too!)\nNone.of().isEmpty()                     // true (known at compile time too!)\n\n// #map\nSome.of(2).map(_ =\u003e _ * 2)              // Some(4)\nNone.of().map(() =\u003e 2)                  // None (known at compile time too!)\n\n// #nonEmpty\nSome.of(2).nonEmpty()                   // true (known at compile time too!)\nNone.of().nonEmpty()                    // false (known at compile time too!)\n\n// #orElse\nSome.of(2).orElse(Option.of(3))         // Some(2)\nNone.of().orElse(Option.of(3))          // Some(3)\n\n// #toString\nSome.of(2).toString()                   // \"Some(2)\"\nNone.of().toString()                    // \"None\"\n```\n\n## Fantasyland\n\nTSOption is [Fantasyland](https://github.com/fantasyland/fantasy-land)-compliant. It implements:\n\n- [x] [Applicative](https://github.com/fantasyland/fantasy-land#applicative)\n- [x] [Apply](https://github.com/fantasyland/fantasy-land#apply)\n- [x] [Chain](https://github.com/fantasyland/fantasy-land#chain)\n- [x] [Functor](https://github.com/fantasyland/fantasy-land#functor)\n- [x] [Monad](https://github.com/fantasyland/fantasy-land#monad)\n\n### Fantasyland-Compatible API\n\n```ts\nimport * as fl from 'fantasy-land'\nconst {ap, chain, map, of} = fl\n\n// Create an option\nOption[of](3)                           // Some(3)\nOption[of]('abc')                       // Some('abc')\nOption[of](null)                        // None\nOption[of](undefined)                   // None\n\n// #chain\nOption[of](3)[chain](_ =\u003e Option[of](_ * 2)) // Some(6)\nOption[of](null)[chain](() =\u003e Option[of](2)) // None (known at compile time too!)\n\n// #map\nOption[of](2)[map](_ =\u003e _ * 2)          // Some(4)\nOption[of](null)[map](() =\u003e 2)          // None (known at compile time too!)\n\n// #ap\nOption[of](2)[ap](Option[of]((_: number) =\u003e _ * 2)) // Some(4)\nOption[of](null)[ap](Option[of](() =\u003e 2)) // None (known at compile time too!)\n```\n\n## Tests\n\n```sh\nnpm test\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcherny%2Ftsoption","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbcherny%2Ftsoption","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbcherny%2Ftsoption/lists"}