{"id":15043289,"url":"https://github.com/bromne/typescript-optional","last_synced_at":"2025-04-06T01:10:26.340Z","repository":{"id":25699332,"uuid":"105300950","full_name":"bromne/typescript-optional","owner":"bromne","description":"Optional (like Java) implementation in TypeScript","archived":false,"fork":false,"pushed_at":"2023-11-16T14:50:47.000Z","size":280,"stargazers_count":117,"open_issues_count":7,"forks_count":16,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-30T00:08:23.944Z","etag":null,"topics":["java-8","optional","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/typescript-optional","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/bromne.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}},"created_at":"2017-09-29T17:44:43.000Z","updated_at":"2024-05-30T09:01:12.000Z","dependencies_parsed_at":"2024-06-18T13:57:01.769Z","dependency_job_id":null,"html_url":"https://github.com/bromne/typescript-optional","commit_stats":{"total_commits":116,"total_committers":5,"mean_commits":23.2,"dds":0.06896551724137934,"last_synced_commit":"1fadb79ac3865bf3cfcac17709720a0fd68c7865"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bromne%2Ftypescript-optional","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bromne%2Ftypescript-optional/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bromne%2Ftypescript-optional/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bromne%2Ftypescript-optional/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bromne","download_url":"https://codeload.github.com/bromne/typescript-optional/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247419861,"owners_count":20936012,"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":["java-8","optional","typescript"],"created_at":"2024-09-24T20:48:48.730Z","updated_at":"2025-04-06T01:10:26.311Z","avatar_url":"https://github.com/bromne.png","language":"TypeScript","readme":"# TypeScript Optional\r\n\r\n[![npm](https://img.shields.io/npm/v/typescript-optional.svg)](https://www.npmjs.com/package/typescript-optional)\r\n[![License](https://img.shields.io/npm/l/typescript-optional.svg)](https://www.npmjs.com/package/typescript-optional)\r\n[![codecov](https://codecov.io/gh/bromne/typescript-optional/branch/master/graph/badge.svg?token=vwg9UEGoic)](https://codecov.io/gh/bromne/typescript-optional)\r\n\r\nOptional (like Java) implementation in TypeScript\r\n\r\n## Overview\r\n\r\n`Optional\u003cT\u003e` is a type which *may* or *may not* contain a *payload* of type `T`.\r\nIt provides a common interface regardless of whether an instance is *present* or is *empty*. \r\n\r\nThis module is inspired by [Optional class in Java 8+](https://docs.oracle.com/javase/10/docs/api/java/util/Optional.html).\r\n\r\n The following methods are currently not supported:\r\n \r\n - `equals`\r\n - `toString`\r\n - `hashCode`\r\n - `stream`\r\n\r\n### Install\r\n\r\n```\r\nnpm install --save typescript-optional\r\n```\r\n\r\n## Usage\r\n\r\n### import\r\n\r\n```ts\r\n// import Optional type from this module\r\nimport { Optional } from \"typescript-optional\";\r\n```\r\n\r\n### creating `Optional\u003cT\u003e` objects\r\n\r\n```ts\r\nconst nullableString: string | null = /* some nullable value */;\r\n\r\n// all the following variables will be parameterized as Optional\u003cstring\u003e.\r\nconst optional = Optional.ofNullable(nullableString);\r\nconst optionalPresent1 = Optional.ofNullable(\"foo\");\r\nconst optionalPresent2 = Optional.ofNonNull(\"foo\"); // accepts non-null value (or else throws TypeError)\r\nconst optionalEmpty1: Optional\u003cstring\u003e = Optional.empty(); // type hinting required\r\nconst optionalEmpty2 = Optional.empty\u003cstring\u003e(); // or parameterize explicitly\r\n```\r\n\r\n### operations\r\n\r\n```ts\r\nconst optional: Optional\u003cstring\u003e = Optional.ofNullable( /* some optional value: null | string */ );\r\n\r\n// force to retrieve the payload. (or else throws TypeError.)\r\n// this method is not used match.\r\noptional.get();\r\n\r\n// represent whether this is present or not.\r\noptional.isPresent();\r\n\r\n// represent whether this is empty or not. (negation of `isPresent` property)\r\noptional.isEmpty();\r\n\r\n// if a payload is present, execute the given `consumer`.\r\noptional.ifPresent(value =\u003e console.log(value));\r\n\r\n// if a payload is present, execute the first argument (`consumer`),\r\n// otherwise execute the second argument (emptyAction).\r\noptional.ifPresentOrElse(value =\u003e console.log(value), () =\u003e console.log(\"empty\"));\r\n\r\n// filter a payload with additional predicate.\r\noptional.filter(value =\u003e value.length \u003e 0);\r\n\r\n// map a payload with the given mapper.\r\noptional.map(value =\u003e value.length);\r\n\r\n// map a payload with the given mapper which returns value wrapped with Optional type.\r\nconst powerIfPositive: (x: Number) =\u003e Optional\u003cNumber\u003e\r\n    = x =\u003e (x \u003e 0) ? Optional.ofNonNull(x * x) : Optional.empty();\r\nconst numberOptional: Optional\u003cnull | number\u003e = Optional.ofNullable(/* some optional value: null | number */)\r\nnumberOptional.flatMap(value =\u003e powerIfPositive(value as number));\r\n\r\n// if this is present, return this, otherwise return the given another optional.\r\nconst another: Optional\u003cstring\u003e = Optional.ofNullable(/* ... */);\r\noptional.or(another);\r\n\r\n// if this is present retrieve the payload,\r\n// otherwise return the given value.\r\noptional.orElse(\"bar\");\r\n\r\n// if a payload is present, retrieve the payload, \r\n// otherwise return a value supplied by the given function.\r\noptional.orElseGet(() =\u003e \"bar\");\r\n\r\n// if a payload is present, retrieve the payload,\r\n// otherwise throw an exception supplied by the given function.\r\noptional.orElseThrow(() =\u003e new Error());\r\n\r\n// if a payload is present, retrieve the payload,\r\n// otherwise return null.\r\noptional.orNull();\r\n\r\n// if a payload is present, retrieve the payload,\r\n// otherwise return undefined.\r\noptional.orUndefined();\r\n\r\n// return an appropriate result by emulating pattern matching with the given cases.\r\noptional.matches({\r\n    present: value =\u003e value.length,\r\n    empty: () =\u003e 0, \r\n})\r\n\r\n// convert this to an Option value.\r\noptional.toOption();\r\n```\r\n\r\n### prototype-free types\r\n\r\nWhile `Optional`'s fluent interface for method chaining with `prototype` is usually useful and elegant,\r\nrelying on `prototype` can cause some problems in certain situations like that an external function copies such objects *except* `prototype`.\r\nFor example, `setState` of React reflects the given value as a state except the value's `prototype` (and then you will see \"TypeError: undefined is not a function\" in runtime though TypeScript compilation has been succeeded!).\r\n\r\nTo avoid this issue, you have three options that *convert* an `Optional` into a *prototype-free*, or a simple JavaScript object (associative array, string etc.).\r\n\r\n- `Optional.orNull`\r\n- `Optional.orUndefined`\r\n- `Optional.toOption`\r\n\r\n#### `Optional.orNull` and `Optional.orUndefined`\r\n\r\nUsing `Optional.orNull` or `Optional.orUndefined` is the simple way to obtain prototype-free objects.\r\nThese methods convert an `Optional\u003cT\u003e` into a value of *type union*.\r\n\r\n`Optional\u003cT\u003e.orNull` returns `T | null`.\r\n\r\n`Optional\u003cT\u003e.orUndefined` returns `T | undefined`. The `T | undefined` type is compatible with [optional parameters and properties](http://www.typescriptlang.org/docs/handbook/advanced-types.html#optional-parameters-and-properties) of TypeScript.\r\n\r\nUse `Optional.ofNullable` to restore an Optional value from a value of these type unions.\r\n\r\n```ts\r\nconst update: \u003cT\u003e (original: T) =\u003e T = /* some external function that returns without the prototype */\r\nconst optional: Optional\u003cstring\u003e = /* some Optional object */;\r\n\r\nlet nullable: string | null = optional.orNull();\r\nlet orUndefined: string | undefined = optional.orUndefined();\r\n\r\n// update using external functions!\r\nnullable = update(nullable);\r\norUndefined = update(orUndefined);\r\n\r\n// retore from (string | null).\r\nconst optionalFromNullable: Optional\u003cstring\u003e = Optional.ofNullble(nullable);\r\n\r\n// restore from (string | undefined).\r\nconst optionalFromOrUndefined: Optional\u003cstring\u003e = Optional.ofNullble(orUndefined);\r\n```\r\n\r\n#### `Option.toOption`\r\n\r\nAs a more explicit way to obtain prototype-free objects, `Optional.toOption` is provided.\r\nThis method convert an `Optional\u003cT\u003e` into an object of `Option\u003cT\u003e` type, which conforms to [*discriminated unions*](http://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions) also known as *algebraic data types*.\r\nRefer the [API document](lib/types.ts) of `Option\u003cT\u003e` to learn about the structure.\r\n\r\n```ts\r\nconst update: \u003cT\u003e (original: Option\u003cT\u003e) =\u003e T = /* some external function that returns without the prototype */\r\nconst optional: Optional\u003cstring\u003e = /* some Optional value */;\r\n\r\nlet option: Option\u003cstring\u003e = optional.toOption();\r\n\r\n// update using external functions!\r\noption = update(option);\r\n\r\n// restore from Option\u003cT\u003e.\r\nconst optionalFromOption: Optional\u003cstring\u003e = Optional.from(option);\r\n```\r\n\r\n## License\r\n\r\nMIT License - [LICENSE.md](LICENSE.md)\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbromne%2Ftypescript-optional","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbromne%2Ftypescript-optional","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbromne%2Ftypescript-optional/lists"}