{"id":13496248,"url":"https://github.com/stefano-regosa-deel/pattern-matching-ts","last_synced_at":"2025-03-28T18:31:45.027Z","repository":{"id":39519088,"uuid":"311588271","full_name":"stefano-regosa-deel/pattern-matching-ts","owner":"stefano-regosa-deel","description":"⚡ Pattern Matching in Typescript","archived":false,"fork":false,"pushed_at":"2021-08-30T10:59:22.000Z","size":1766,"stargazers_count":189,"open_issues_count":2,"forks_count":8,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-18T11:13:49.862Z","etag":null,"topics":["fp","fp-ts","functional-programming","matching","option-monad","pattern","pattern-matching","typescript","typescript-pattern-matching"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/pattern-matching-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/stefano-regosa-deel.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-11-10T08:09:12.000Z","updated_at":"2024-12-23T14:24:00.000Z","dependencies_parsed_at":"2022-08-12T11:50:44.879Z","dependency_job_id":null,"html_url":"https://github.com/stefano-regosa-deel/pattern-matching-ts","commit_stats":null,"previous_names":["stefano-regosa-deel/pattern-matching-ts","nrdlab/pattern-matching-ts"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefano-regosa-deel%2Fpattern-matching-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefano-regosa-deel%2Fpattern-matching-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefano-regosa-deel%2Fpattern-matching-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefano-regosa-deel%2Fpattern-matching-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stefano-regosa-deel","download_url":"https://codeload.github.com/stefano-regosa-deel/pattern-matching-ts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246080622,"owners_count":20720562,"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":["fp","fp-ts","functional-programming","matching","option-monad","pattern","pattern-matching","typescript","typescript-pattern-matching"],"created_at":"2024-07-31T19:01:44.538Z","updated_at":"2025-03-28T18:31:44.319Z","avatar_url":"https://github.com/stefano-regosa-deel.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/nrdlab/pattern-matching-ts/blob/master/img/pattern-matching-ts.png?raw=true\"\u003e\n\u003c/div\u003e\n\n\u003ch4 align=\"center\"\u003e\n  \u003cstrong\u003ePattern matching\u003c/strong\u003e in \u003cstrong\u003eTypescript\u003c/strong\u003e.\n\u003c/h4\u003e\n\n\u003cp\u003e\n  \u003cstrong\u003ePattern Matching\u003c/strong\u003e is a declarative much more powerful and less verbose alternative to imperatives \u003ci\u003e\"if/else\"\u003c/i\u003e conditions.\u003cbr/\u003e\n  A definition can be found inside \u003ca href=\"https://docs.scala-lang.org/tour/pattern-matching.html\"\u003e\u003cstrong\u003eScala Documentation\u003c/strong\u003e\u003c/a\u003e\u003cbr\u003e\u003cbr\u003e\n\u003ci\u003e“Pattern matching tests whether a given value (or sequence of values) has the shape defined by a pattern, and, if it does, binds the variables in the pattern to the corresponding components of the value (or sequence of values).”\u003c/i\u003e\u003cbr\u003e\u003cbr\u003e\n  In \u003cstrong\u003eFunctional Programming languages\u003c/strong\u003e, there're built-in keywords for \u003cstrong\u003ePattern Matching\u003c/strong\u003e. \u003cstrong\u003eTypescript\u003c/strong\u003e though is one language that works very well with \u003cstrong\u003eFunctional Programming\u003c/strong\u003e but lacks this feature.\u003cbr/\u003e\nThis package aims to bring \u003cstrong\u003ePattern Matching\u003c/strong\u003e feature to \u003cstrong\u003eTypescript\u003c/strong\u003e through \u003cstrong\u003eDiscriminated Union Types\u003c/strong\u003e / \u003cstrong\u003eAlgebraic Data Types\u003c/strong\u003e.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/v/pattern-matching-ts?color=green\u0026logo=yarn\u0026logoColor=white\u0026style=flat-square\"\u003e\n      \u003ca href=\"https://codecov.io/gh/nrdlab/pattern-matching-ts\"\u003e\n        \u003cimg src=\"https://codecov.io/gh/nrdlab/pattern-matching-ts/branch/master/graph/badge.svg?token=1V23E6VDHN\"/\u003e\n      \u003c/a\u003e\n\u003ca href=\"https://github.com/nrdlab/pattern-matching-ts/blob/master/LICENSE\"\u003e\u003cimg alt=\"GitHub license\" src=\"https://img.shields.io/github/license/nrdlab/pattern-matching-ts?style=flat-square\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/nrdlab/pattern-matching-ts/stargazers\"\u003e\u003cimg alt=\"GitHub stars\" src=\"https://img.shields.io/github/stars/nrdlab/pattern-matching-ts?color=green\u0026style=flat-square\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/nrdlab/pattern-matching-ts/network\"\u003e\u003cimg alt=\"GitHub forks\" src=\"https://img.shields.io/github/forks/nrdlab/pattern-matching-ts?color=green\u0026style=flat-square\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/nrdlab/pattern-matching-ts/actions?query=workflow%3ACI\"\u003e\n  \u003cimg alt=\"GitHub Workflow Status\" src=\"https://img.shields.io/github/workflow/status/nrdlab/pattern-matching-ts/CI?style=flat-square\u0026color=green\"\u003e\n  \u003ca\u003e\n\u003c/p\u003e\n\n\u003cbr /\u003e\n\n# Index\n\n- [Installation](#installation)\n- [Usage](#usage)\n\n---\n\n- [Match](#match)\n  - [Match Option](#option-match)\n  - [Match Default ](#default-match)\n- [MatchW](#matchW)\n  - [MatchW Option](#option-MatchW)\n  - [MatchW Either](#either-MatchW)\n  - [MatchW Default](#default-matchW)\n\n---\n\n- [License](#license)\n\n# Installation\n\n**yarn**\n\n```sh\nyarn add pattern-matching-ts\n```\n\n**npm**\n\n```sh\nnpm install --save pattern-matching-ts\n```\n\n# Usage\n\n**_MatchW_**\n\n\u003e ### Option MatchW\n\n```ts\nimport * as M from 'pattern-matching-ts/lib/match'\nimport { pipe } from 'fp-ts/lib/function'\nimport * as O from 'fp-ts/lib/Option'\n\nconst optionMatching = (o: unknown) =\u003e\n  pipe(\n    o,\n    M.matchW('_tag')({\n      Some: ({ value }) =\u003e 'Something: ' + value,\n      None: () =\u003e 'Nothing',\n      _: () =\u003e 'Default'\n    })\n  )\n\nassert.deepStrictEqual(optionMatching(O.some('data')), 'Something: data')\nassert.deepStrictEqual(optionMatching(O.none), 'Nothing')\nassert.deepStrictEqual(optionMatching((undefined as unknown) as O.None), 'Default')\n```\n\n\u003e ### Either MatchW\n\n```ts\nimport * as M from 'pattern-matching-ts/lib/match'\nimport { pipe } from 'fp-ts/lib/function'\nimport * as E from 'fp-ts/lib/Either'\n\ntype RGB = Record\u003c'r' | 'g' | 'b', number\u003e\nconst either = (maybeRgb: E.Either\u003cstring, RGB\u003e) =\u003e\n  pipe(\n    maybeRgb,\n    M.matchW('_tag')({\n      Left: ({ left }) =\u003e 'Error: ' + left,\n      Right: ({ right: { r, g, b } }) =\u003e `Red: ${r} | Green: ${g} | Blue: ${b}`\n    })\n  )\n\nassert.deepStrictEqual(either(E.right({ r: 255, g: 255, b: 0 })), 'Red: 255 | Green: 255 | Blue: 0')\n```\n\n\u003e ### Default MatchW\n\n```ts\nimport * as M from 'pattern-matching-ts/lib/match'\nimport { pipe } from 'fp-ts/lib/function'\n\ninterface ServerResponse\u003cCode extends string | number\u003e {\n  readonly code: Code\n}\n\ninterface Response\u003cBody\u003e {\n  readonly response: {\n    readonly body: Body\n  }\n}\n\ninterface Success extends ServerResponse\u003c200\u003e, Response\u003cReadonlyArray\u003cstring\u003e\u003e {}\n\ninterface NotFoundError extends ServerResponse\u003c404\u003e {}\n\ninterface ServerError extends ServerResponse\u003c500\u003e {\n  readonly detail: string\n}\n\ntype Responses = Success | NotFoundError | ServerError\n\nconst matchResponse = (response: Responses) =\u003e\n  pipe(\n    response,\n    M.matchW('code')({\n      500: ({ detail }) =\u003e ({ message: 'Internal server error', detail }),\n      404: () =\u003e ({ message: 'The page cannot be found!' }),\n      200: ({ response }) =\u003e response.body,\n      _: () =\u003e 'Unexpected response'\n    })\n  )\n\nassert.deepStrictEqual(either(E.right({ r: 255, g: 255, b: 0 })), 'Red: 255 | Green: 255 | Blue: 0')\nassert.deepStrictEqual(matchResponse({ code: 200, response: { body: ['data'] } }), ['data'])\nassert.deepStrictEqual(matchResponse({ code: 500, detail: 'Cannot connect to the database' }), {\n  message: 'Internal server error',\n  detail: 'Cannot connect to the database'\n})\nassert.deepStrictEqual(matchResponse({ code: 404 }), { message: 'The page cannot be found!' })\n```\n\n**_Match_**\n\n\u003e ### Option Match \n\n```ts\nimport * as M from 'pattern-matching-ts/lib/match'\nimport * as O from 'fp-ts/lib/Option'\n\nconst optionMatching = M.match\u003cO.Option\u003cstring\u003e, string\u003e({\n  Some: (x) =\u003e `Something: ${x.value}`,\n  None: () =\u003e 'Nothing'\n})\n\nassert.deepStrictEqual(optionMatching(O.some('data')), 'Something: data')\nassert.deepStrictEqual(optionMatching(O.none), 'Nothing')\n```\n\n\u003e ### Default Match\n\n```ts\nimport * as M from 'pattern-matching-ts/lib/match'\n\ninterface ChangeColor\u003cT = number\u003e {\n  readonly _tag: 'ChangeColor'\n  readonly value: {\n    readonly r: T\n    readonly g: T\n    readonly b: T\n  }\n}\ninterface Move\u003cT = number\u003e {\n  readonly _tag: 'Move'\n  readonly value: {\n    readonly x: T\n    readonly y: T\n  }\n}\ninterface Write {\n  readonly _tag: 'Write'\n  readonly value: {\n    readonly text: string\n  }\n}\n\ntype Cases = ChangeColor\u003cnumber\u003e | Move | Write\nconst matchMessage = M.match\u003cCases, string\u003e({\n  ChangeColor: ({ value: { r, g, b } }) =\u003e `Change the color to Red: ${r} | Green: ${g} | Blue: ${b}`,\n  Move: ({ value: { x, y } }) =\u003e `Move in the x direction: ${x} and in the y direction: ${y}`,\n  Write: ({ value: { text } }) =\u003e `Text message: ${text}`,\n  _: () =\u003e 'Default message'\n})\n\nconst ChangeColor = ({ r, g, b }: ChangeColor\u003cnumber\u003e['value']): ChangeColor\u003cnumber\u003e =\u003e ({\n  _tag: 'ChangeColor',\n  value: { r, g, b }\n})\n\nconst Move = ({ x, y }: Move['value']): Move =\u003e ({\n  _tag: 'Move',\n  value: { x, y }\n})\n\nconst Write = ({ text }: Write['value']): Write =\u003e ({\n  _tag: 'Write',\n  value: { text }\n})\n\nassert.deepStrictEqual(\n  matchMessage(Move({ x: 500, y: 100 })),\n  'Move in the x direction: 500 and in the y direction: 100'\n)\n\nassert.deepStrictEqual(\n  matchMessage(ChangeColor({ r: 12, g: 20, b: 30 })),\n  'Change the color to Red: 12 | Green: 20 | Blue: 30'\n)\n\nassert.deepStrictEqual(matchMessage(Write({ text: 'my message' })), 'Text message: my message')\n```\n\nBlog posts that introduces the API.\n\n 👉 [Pattern Matching in Typescript](https://dev.to/stefano_regosa/typescript-pattern-matching-ne8)\n\n 👉 [Pipeable Pattern Matching in Typescript](https://dev.to/stefano_regosa/pipeable-pattern-matching-in-typescript-33dn)\n\n\n[MIT](/LICENSE.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefano-regosa-deel%2Fpattern-matching-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstefano-regosa-deel%2Fpattern-matching-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefano-regosa-deel%2Fpattern-matching-ts/lists"}