{"id":23417377,"url":"https://github.com/lockblock-dev/poc-ts-option-and-result-type","last_synced_at":"2026-07-15T11:34:24.790Z","repository":{"id":268895228,"uuid":"902503651","full_name":"LockBlock-dev/poc-ts-option-and-result-type","owner":"LockBlock-dev","description":"(PoC) Basic implementation of Rust's Option and Result type in TypeScript","archived":false,"fork":false,"pushed_at":"2024-12-19T14:19:57.000Z","size":6,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-25T20:13:32.609Z","etag":null,"topics":["option-type","optional","result-type","rust-option","rust-result","type-safety"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":false,"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/LockBlock-dev.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":"2024-12-12T17:36:07.000Z","updated_at":"2024-12-19T14:20:01.000Z","dependencies_parsed_at":"2024-12-19T15:40:00.881Z","dependency_job_id":null,"html_url":"https://github.com/LockBlock-dev/poc-ts-option-and-result-type","commit_stats":null,"previous_names":["lockblock-dev/poc-ts-option-and-result-type"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/LockBlock-dev/poc-ts-option-and-result-type","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LockBlock-dev%2Fpoc-ts-option-and-result-type","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LockBlock-dev%2Fpoc-ts-option-and-result-type/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LockBlock-dev%2Fpoc-ts-option-and-result-type/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LockBlock-dev%2Fpoc-ts-option-and-result-type/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LockBlock-dev","download_url":"https://codeload.github.com/LockBlock-dev/poc-ts-option-and-result-type/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LockBlock-dev%2Fpoc-ts-option-and-result-type/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35503618,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-15T02:00:06.706Z","response_time":131,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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","optional","result-type","rust-option","rust-result","type-safety"],"created_at":"2024-12-22T23:18:02.109Z","updated_at":"2026-07-15T11:34:24.743Z","avatar_url":"https://github.com/LockBlock-dev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PoC TypeScript Option and Result type\n\nThis project implements basic versions of the `Option` and `Result` type, inspired by their counterparts in the Rust programming language, to demonstrate their benefits in TypeScript.\n\n## Motivation\n\nIn Rust, the [`Option`](https://doc.rust-lang.org/stable/core/option/index.html) type is used to represent the presence or absence of a value. The [`Result`](https://doc.rust-lang.org/stable/core/result/index.html) type, on the other hand, is designed for error handling, avoiding exceptions by encouraging explicit handling of both success and failure.\n\nWhile TypeScript supports [truthiness narrowing](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#truthiness-narrowing) to determine if a value is null or undefined, making the `Option` type less crucial, the `Result` type is particularly valuable. It allows developers to represent errors directly in the return type, promoting safer and more predictable error handling by leveraging TypeScript's type system to enforce explicit handling of both success and failure cases, rather than depending on unchecked exceptions.\n\n## Overview\n\n-   [Option](#optiont)\n-   [Result](#resultt-e)\n-   [wrapException](#handling-exceptions-with-wrapexception)\n-   [Typed wrapException](#typed-variant-of-wrapexception)\n\n### [`Option\u003cT\u003e`](./lib/option.ts)\n\nThe `Option` type represent an optional value, either `Some` (a value is present) or `None` (no value). It removes ambiguity and is safer than relying on `null` or `undefined`.\n\n**Example:**\n\n```ts\nimport { type Option, Some, None } from \"./option\";\n\ninterface User {\n    id: number;\n    name: string;\n    address?: string;\n}\n\nconst users: User[] = [\n    { id: 1, name: \"Alice\", address: \"123 Main St\" },\n    { id: 2, name: \"Bob\" },\n    { id: 3, name: \"Charlie\", address: \"456 Oak St\" },\n];\n\nfunction getUserAddress(userId: number): Option\u003cstring\u003e {\n    const user = users.find((u) =\u003e u.id === userId);\n    return user \u0026\u0026 user.address ? Some(user.address) : None;\n}\n\nconst opt = getUserAddress(1);\n// const opt = getUserAddress(2);\n// const opt = getUserAddress(4);\n\nif (opt.isSome()) {\n    // infered string\n    console.log(opt.unwrap());\n} else {\n    // infered never\n    console.log(\"No value\");\n}\n```\n\n### [`Result\u003cT, E\u003e`](./lib/result.ts)\n\nThe `Result` type represents the outcome of an operation that can succeed or fail, either `Ok` (success with a value) or `Err` (failure with an error). It avoids throwing exceptions and provides a functional approach to error handling.\n\n**Example:**\n\n```ts\nimport { type Result, Ok, Err } from \"./result\";\n\nfunction divide(dividend: number, divisor: number): Result\u003cnumber, Error\u003e {\n    if (divisor === 0) {\n        return Err(new Error(\"Cannot divide by zero\"));\n    } else {\n        return Ok(dividend / divisor);\n    }\n}\n\nconst res = divide(10, 2);\n// const res = divide(10, 0);\n\nif (res.isOk()) {\n    // infered number\n    console.log(res.unwrap());\n} else if (res.isErr()) {\n    // infered Error\n    console.error(res.unwrapErr().message);\n}\n```\n\n### Handling exceptions with [`wrapException`](./lib/wrapException.ts)\n\nThe `wrapException` utility helps integrate `Result` with functions that throw exceptions. This works for both synchronous and asynchronous operations.\n\n**Synchronous Example:**\n\n```ts\nimport { type Result } from \"./result\";\nimport wrapException from \"./wrapException\";\n\nconst thisThrows = () =\u003e {\n    throw new Error(\"Something went wrong\");\n    return 42;\n};\n\nconst res = wrapException(() =\u003e thisThrows());\n\nif (res.isOk()) {\n    // infered number\n    console.log(res.unwrap());\n} else if (res.isErr()) {\n    // infered any\n    console.error(res.unwrapErr().message);\n}\n```\n\n**Asynchronous Example:**\n\n```ts\nimport { type Result } from \"./result\";\nimport wrapException from \"./wrapException\";\n\nconst thisThrowsAsync = async () =\u003e {\n    throw new Error(\"Async failure\");\n\n    return await Promise.resolve(1);\n};\n\nconst res = await wrapException(async () =\u003e thisThrowsAsync());\n\nif (res.isOk()) {\n    // infered number\n    console.log(res.unwrap());\n} else if (res.isErr()) {\n    // infered any\n    console.error(res.unwrapErr().message);\n}\n```\n\n### Typed variant of [`wrapException`](./lib/wrapException.ts)\n\nYou can explicitly specify types for the success and error cases.\n\n**Synchronous Example:**\n\n```ts\nimport { type Result } from \"./result\";\nimport wrapException from \"./wrapException\";\n\nconst thisThrows = () =\u003e {\n    throw new Error(\"Something went wrong\");\n\n    return 1;\n};\n\nconst res = wrapException\u003cnumber, Error\u003e(() =\u003e thisThrows());\n\nif (res.isOk()) {\n    // infered number\n    console.log(res.unwrap());\n} else if (res.isErr()) {\n    // infered Error\n    console.error(res.unwrapErr().message);\n}\n```\n\n**Asynchronous Example:**\n\n```ts\nimport { type Result } from \"./result\";\nimport wrapException from \"./wrapException\";\n\nconst thisThrowsAsync = async () =\u003e {\n    throw new Error(\"throwing async\");\n\n    return await Promise.resolve(1);\n};\n\nconst res = await wrapException\u003cReturnType\u003ctypeof thisThrowsAsync\u003e, Error\u003e(\n    async () =\u003e thisThrowsAsync(),\n);\n\nif (res.isOk()) {\n    // infered number\n    console.log(res.unwrap());\n} else if (res.isErr()) {\n    // infered Error\n    console.error(res.unwrapErr().message);\n}\n```\n\n## License\n\nSee the [LICENSE](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flockblock-dev%2Fpoc-ts-option-and-result-type","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flockblock-dev%2Fpoc-ts-option-and-result-type","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flockblock-dev%2Fpoc-ts-option-and-result-type/lists"}