{"id":23719519,"url":"https://github.com/kolharsam/option-ts","last_synced_at":"2026-05-16T11:01:59.181Z","repository":{"id":268046514,"uuid":"862689362","full_name":"kolharsam/option-ts","owner":"kolharsam","description":"option types for typescript","archived":false,"fork":false,"pushed_at":"2026-03-27T01:29:31.000Z","size":338,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-29T21:43:11.798Z","etag":null,"topics":["option-type","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@kolharsam/option-ts","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/kolharsam.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":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-25T02:59:59.000Z","updated_at":"2025-12-15T17:12:20.000Z","dependencies_parsed_at":"2024-12-14T02:48:50.321Z","dependency_job_id":"c5b375a1-9c61-42f9-a775-b16da65fa28a","html_url":"https://github.com/kolharsam/option-ts","commit_stats":null,"previous_names":["kolharsam/option-ts"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/kolharsam/option-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolharsam%2Foption-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolharsam%2Foption-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolharsam%2Foption-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolharsam%2Foption-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kolharsam","download_url":"https://codeload.github.com/kolharsam/option-ts/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kolharsam%2Foption-ts/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33100319,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T04:41:52.686Z","status":"ssl_error","status_checked_at":"2026-05-16T04:41:52.009Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: 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":["option-type","typescript"],"created_at":"2024-12-30T21:52:21.546Z","updated_at":"2026-05-16T11:01:59.138Z","avatar_url":"https://github.com/kolharsam.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/kolharsam/option-ts)\n[![build \u0026 test job](https://github.com/kolharsam/option-ts/actions/workflows/node.js.yml/badge.svg?branch=main)](https://github.com/kolharsam/option-ts/actions/workflows/node.js.yml)\n\n# option-ts\n\nThis library provides Rust-inspired `Option` and `Result` types for TypeScript, enabling more robust error handling and null safety in your TypeScript projects.\n\n## Installation\n\n```bash\nnpm install @kolharsam/option-ts\n```\n\n## Usage\n\n### Option\n\nThe `Option` type represents an optional value: every `Option` is either `Some` and contains a value, or `None`, and does not.\n\n```typescript\nimport { Option, Some, None } from \"@kolharsam/option-ts\";\n\nconst someValue: Option\u003cnumber\u003e = Some(5);\nconst noneValue: Option\u003cnumber\u003e = None();\n\nconsole.log(someValue.isSome()); // true\nconsole.log(noneValue.isNone()); // true\n\n// Transform values safely\nconst doubled = someValue.map((x) =\u003e x * 2);\nconsole.log(doubled.get()); // 10\n\n// Safe division function\nconst safeDiv = (a: number, b: number): Option\u003cnumber\u003e =\u003e {\n  if (b === 0) return None();\n  return Some(a / b);\n};\n\nconsole.log(safeDiv(10, 2).getOrElse(0)); // 5\nconsole.log(safeDiv(10, 0).getOrElse(0)); // 0\n```\n\n#### Pattern Matching with `match`\n\nUse `match` for elegant pattern matching on Option values:\n\n```typescript\nconst result = someValue.match({\n  Some: (value) =\u003e `Got value: ${value}`,\n  None: () =\u003e \"No value found\",\n});\n\n// Real-world example: User greeting\nconst user = Some({ name: \"Alice\", age: 30 });\nconst greeting = user.match({\n  Some: (u) =\u003e `Hello, ${u.name}! You are ${u.age} years old.`,\n  None: () =\u003e \"Hello, guest!\",\n});\nconsole.log(greeting); // \"Hello, Alice! You are 30 years old.\"\n```\n\n### Result\n\nThe `Result` type represents either success (`Ok`) or failure (`Err`). It's useful for functions that can fail.\n\n```typescript\nimport { Result, Ok, Err } from \"@kolharsam/option-ts\";\n\nconst okResult: Result\u003cnumber, string\u003e = Ok(5);\nconst errResult: Result\u003cnumber, string\u003e = Err(\"An error occurred\");\n\nconsole.log(okResult.isOk()); // true\nconsole.log(errResult.isErr()); // true\n\n// Transform success values while preserving errors\nconst doubled = okResult.map((x) =\u003e x * 2);\nconsole.log(doubled.toOk().get()); // 10\n\n// Safe division with detailed error handling\nconst safeDiv = (a: number, b: number): Result\u003cnumber, string\u003e =\u003e {\n  if (b === 0) return Err(\"Division by zero\");\n  return Ok(a / b);\n};\n\nconsole.log(safeDiv(10, 2).unwrapOr(0)); // 5\nconsole.log(safeDiv(10, 0).unwrapOr(0)); // 0\n```\n\n#### Pattern Matching with `match`\n\nUse `match` for comprehensive error handling:\n\n```typescript\nconst handleResult = (input: string): string =\u003e {\n  const parseNumber = (str: string): Result\u003cnumber, string\u003e =\u003e {\n    const num = parseInt(str, 10);\n    return isNaN(num) ? Err(\"Not a number\") : Ok(num);\n  };\n\n  return parseNumber(input).match({\n    Ok: (num) =\u003e `The number is ${num}, squared: ${num * num}`,\n    Err: (error) =\u003e `Error: ${error}`,\n  });\n};\n\nconsole.log(handleResult(\"5\")); // \"The number is 5, squared: 25\"\nconsole.log(handleResult(\"abc\")); // \"Error: Not a number\"\n\n// API response handling\ninterface ApiResponse {\n  data: string[];\n  status: number;\n}\n\nconst processApiResponse = (result: Result\u003cApiResponse, string\u003e) =\u003e {\n  return result.match({\n    Ok: (response) =\u003e response.data.map((item) =\u003e item.toUpperCase()),\n    Err: (error) =\u003e [`Error: ${error}`],\n  });\n};\n```\n\n## API Reference\n\n### Option\u003cT\u003e\n\n- `Some\u003cT\u003e(value: T): Option\u003cT\u003e`\n- `None\u003cT\u003e(): Option\u003cT\u003e`\n- `get(): T`\n- `getOrElse(defaultValue: T): T`\n- `map\u003cU\u003e(fn: (val: T) =\u003e U): Option\u003cU\u003e`\n- `inspect(fn: (val: T) =\u003e void): Option\u003cT\u003e`\n- `isSome(): boolean`\n- `isNone(): boolean`\n- `isSomeAnd(fn: (val: T) =\u003e boolean): boolean`\n- `isNoneOr(fn: (val: T) =\u003e boolean): boolean`\n- `asSlice(): T[] | []`\n- `expect(msg: string): T`\n- `unwrap(): T`\n- `unwrapOr(def: T): T`\n- `unwrapOrElse(fn: () =\u003e T): T`\n- `mapOr\u003cU\u003e(def: U, fn: (val: T) =\u003e U): U`\n- `mapOrElse\u003cU\u003e(def: () =\u003e U, fn: (val: T) =\u003e U): U`\n- `okOr\u003cE\u003e(err: E): Result\u003cT, E\u003e`\n- `okOrElse\u003cE\u003e(fn: () =\u003e E): Result\u003cT, E\u003e`\n- `and\u003cU\u003e(optionB: Option\u003cU\u003e): Option\u003cU\u003e`\n- `andThen\u003cU\u003e(fn: (val: T) =\u003e Option\u003cU\u003e): Option\u003cU\u003e`\n- `or(optionB: Option\u003cT\u003e): Option\u003cT\u003e`\n- `orElse(optFn: () =\u003e Option\u003cT\u003e): Option\u003cT\u003e`\n- `xor(optionB: Option\u003cT\u003e): Option\u003cT\u003e`\n- `zip\u003cU\u003e(other: Option\u003cU\u003e): Option\u003c[T, U]\u003e`\n- `zipWith\u003cU, V\u003e(other: Option\u003cU\u003e, fn: (current: T, other: U) =\u003e V): Option\u003cV\u003e`\n- `match\u003cU\u003e(patterns: { Some: (value: T) =\u003e U; None: () =\u003e U }): U`\n\n### Result\u003cT, E\u003e\n\n- `Ok\u003cT, E\u003e(value: T): Result\u003cT, E\u003e`\n- `Err\u003cT, E\u003e(error: E): Result\u003cT, E\u003e`\n- `isOk(): boolean`\n- `isOkAnd(fn: (val: T) =\u003e boolean): boolean`\n- `isErr(): boolean`\n- `isErrAnd(fn: (val: E) =\u003e boolean): boolean`\n- `toOk(): Option\u003cT\u003e`\n- `toErr(): Option\u003cE\u003e`\n- `inspect(fn: (val: T) =\u003e void): Result\u003cT, E\u003e`\n- `inspectErr(fn: (val: E) =\u003e void): Result\u003cT, E\u003e`\n- `map\u003cV\u003e(f: (val: T) =\u003e V): Result\u003cV, E\u003e`\n- `mapOr\u003cV\u003e(def: V, f: (val: T) =\u003e V): V`\n- `mapErr\u003cF\u003e(fn: (err: E) =\u003e F): Result\u003cT, F\u003e`\n- `expect(msg: string): T`\n- `unwrap(): T`\n- `unwrapOrDefault(def: T): T`\n- `expectErr(msg: string): E`\n- `unwrapErr(): E`\n- `and\u003cV\u003e(res: Result\u003cV, E\u003e): Result\u003cV, E\u003e`\n- `andThen\u003cV\u003e(op: (val: T) =\u003e Result\u003cV, E\u003e): Result\u003cV, E\u003e`\n- `or\u003cF\u003e(res: Result\u003cT, F\u003e): Result\u003cT, F\u003e`\n- `orElse\u003cF\u003e(op: (err: E) =\u003e Result\u003cT, F\u003e): Result\u003cT, F\u003e`\n- `unwrapOr(def: T): T`\n- `unwrapOrElse(op: (err: E) =\u003e T): T`\n- `match\u003cV\u003e(patterns: { Ok: (value: T) =\u003e V; Err: (error: E) =\u003e V }): V`\n\n### Utility Functions\n\n- `unzip\u003cT, U\u003e(option: Option\u003c[T, U]\u003e): [Option\u003cT\u003e, Option\u003cU\u003e]`\n- `transpose\u003cT, E\u003e(option: Option\u003cResult\u003cT, E\u003e\u003e): Result\u003cOption\u003cT\u003e, E\u003e`\n- `flatten\u003cT\u003e(option: Option\u003cOption\u003cT\u003e\u003e): Option\u003cT\u003e`\n- `transposeResult\u003cT, E\u003e(res: Result\u003cOption\u003cT\u003e, E\u003e): Option\u003cResult\u003cT, E\u003e\u003e`\n- `flattenResult\u003cT, E\u003e(res: Result\u003cResult\u003cT, E\u003e, E\u003e): Result\u003cT, E\u003e`\n\n## Advanced Usage\n\n### Chaining Operations\n\nBoth `Option` and `Result` support method chaining for elegant composition:\n\n```typescript\n// Option chaining\nconst user = Some({ name: \"Alice\", scores: [85, 92, 78] });\nconst result = user\n  .map((u) =\u003e u.scores)\n  .map((scores) =\u003e scores.reduce((a, b) =\u003e a + b, 0) / scores.length)\n  .map((avg) =\u003e Math.round(avg))\n  .match({\n    Some: (avg) =\u003e `Average score: ${avg}`,\n    None: () =\u003e \"No scores available\",\n  });\n\n// Result chaining with error handling\nconst processUserData = (input: string) =\u003e\n  parseJson(input)\n    .andThen(validateUser)\n    .andThen(calculateMetrics)\n    .match({\n      Ok: (metrics) =\u003e `Success: ${JSON.stringify(metrics)}`,\n      Err: (error) =\u003e `Failed: ${error}`,\n    });\n```\n\n### Working with Collections\n\nTransform arrays safely using Option and Result:\n\n```typescript\n// Find first even number\nconst numbers = [1, 3, 5, 8, 9];\nconst firstEven = numbers.find((n) =\u003e n % 2 === 0)\n  ? Some(numbers.find((n) =\u003e n % 2 === 0)!)\n  : None\u003cnumber\u003e();\n\nfirstEven.match({\n  Some: (num) =\u003e console.log(`First even: ${num}`),\n  None: () =\u003e console.log(\"No even numbers found\"),\n});\n\n// Process array with potential failures\nconst safeParseNumbers = (strings: string[]): Result\u003cnumber[], string\u003e =\u003e {\n  const results = strings.map((s) =\u003e {\n    const num = parseInt(s, 10);\n    return isNaN(num) ? Err(`Invalid: ${s}`) : Ok(num);\n  });\n\n  const failures = results.filter((r) =\u003e r.isErr());\n  if (failures.length \u003e 0) {\n    return Err(\n      `Parse errors: ${failures.map((f) =\u003e f.unwrapErr()).join(\", \")}`\n    );\n  }\n\n  return Ok(results.map((r) =\u003e r.unwrap()));\n};\n```\n\n### Integration with Async/Await\n\nCombine with promises for robust async error handling:\n\n```typescript\nasync function fetchUser(id: string): Promise\u003cResult\u003cUser, string\u003e\u003e {\n  try {\n    const response = await fetch(`/api/users/${id}`);\n    if (!response.ok) {\n      return Err(`HTTP ${response.status}: ${response.statusText}`);\n    }\n    const user = await response.json();\n    return Ok(user);\n  } catch (error) {\n    return Err(`Network error: ${error.message}`);\n  }\n}\n\n// Usage\nconst result = await fetchUser(\"123\");\nconst message = result.match({\n  Ok: (user) =\u003e `Welcome, ${user.name}!`,\n  Err: (error) =\u003e `Login failed: ${error}`,\n});\n```\n\n## Best Practices\n\n1. **Prefer `match` for complex logic**: Use `match` when you need to handle both cases with different logic.\n\n2. **Use specific error types**: Instead of generic strings, consider using custom error types for better type safety.\n\n3. **Chain operations**: Take advantage of method chaining for readable data transformations.\n\n4. **Avoid unwrap() in production**: Use `unwrapOr()`, `unwrapOrElse()`, or `match` for safer error handling.\n\n5. **Combine with TypeScript**: Leverage TypeScript's type system for even better safety:\n\n```typescript\ntype ApiError = \"NetworkError\" | \"AuthError\" | \"ValidationError\";\n\nfunction apiCall(): Result\u003cData, ApiError\u003e {\n  // Implementation\n}\n\n// TypeScript will ensure all error cases are handled\napiCall().match({\n  Ok: (data) =\u003e processData(data),\n  Err: (error) =\u003e {\n    switch (error) {\n      case \"NetworkError\":\n        return retryRequest();\n      case \"AuthError\":\n        return redirectToLogin();\n      case \"ValidationError\":\n        return showValidationErrors();\n    }\n  },\n});\n```\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkolharsam%2Foption-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkolharsam%2Foption-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkolharsam%2Foption-ts/lists"}