{"id":24011926,"url":"https://github.com/dkendal/match-ts","last_synced_at":"2025-04-15T06:51:28.280Z","repository":{"id":45940691,"uuid":"407037514","full_name":"Dkendal/match-ts","owner":"Dkendal","description":"Pattern matching for Javascript","archived":false,"fork":false,"pushed_at":"2022-01-23T01:41:58.000Z","size":189,"stargazers_count":25,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-15T06:51:26.404Z","etag":null,"topics":["javascript","matching","nodejs","nodejs-library","pattern","pattern-matching","typescript","typescript-library"],"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/Dkendal.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","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":"2021-09-16T05:48:51.000Z","updated_at":"2024-02-15T05:42:28.000Z","dependencies_parsed_at":"2022-09-26T21:31:44.608Z","dependency_job_id":null,"html_url":"https://github.com/Dkendal/match-ts","commit_stats":null,"previous_names":["dkendal/pattern-match.js"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dkendal%2Fmatch-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dkendal%2Fmatch-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dkendal%2Fmatch-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Dkendal%2Fmatch-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Dkendal","download_url":"https://codeload.github.com/Dkendal/match-ts/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249023708,"owners_count":21199958,"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":["javascript","matching","nodejs","nodejs-library","pattern","pattern-matching","typescript","typescript-library"],"created_at":"2025-01-08T05:43:09.887Z","updated_at":"2025-04-15T06:51:28.262Z","avatar_url":"https://github.com/Dkendal.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @dkendal/match\n\nProvides pattern matching features typically found in functional\nlanguages like Elixir/Erlang, ML, F\\#, etc.\n\n## Installation\n\n```sh\nyarn add @dkendal/match\n```\n\n## The `match` function\n\nThe match function lets us compare a value against many patterns until\nwe find one that matches.\n\n```typescript\nimport { __, match, when } from '@dkendal/match'\n\nmatch(\n  [1, 2, 3],\n  when([4, 5, 6], () =\u003e \"This clause won't match\"),\n  when([1, __, 3], () =\u003e 'This clause will match, __ will match any value'),\n  when(__, () =\u003e 'This clause would match any value'),\n)\n\n'This clause will match, __ will match any value'\n```\n\nThe value that was passed into `match` is also passed to the callback:\n\n```typescript\nconst x = 10\n\nmatch(\n  x,\n  when(__, (value) =\u003e value * 10),\n)\n100\n```\n\nIf none of the cases match and error is thrown:\n\n```typescript\nmatch([1, 2, 3]\n      when([1, 2], () =\u003e \"this won't match as the array lengths don't agree\"))\n// (Error) unmatched case: [1, 2, 3]\n```\n\n## The `when` function\n\nThe `when` function exists purely for typing. When you use it gives the callback\nthe proper type expressed in the left-hand-side pattern:\n\n```typescript\nwhen(\n  V('checkout', {\n    type: 'checkout',\n    lineItems: [V('firstLineItem', { type: 'line_item', data: __ }), __.rest],\n  }),\n  ({ checkout, firstLineItem }) =\u003e {\n    var checkout: {\n      type: 'checkout'\n      id: number\n      lineItems: [{\n        type: 'line_item'\n        id: number\n        data: any\n      }, any[]]\n    }\n\n    var firstLineItem: {\n      type: 'line_item'\n      id: number\n      data: any\n    }\n  },\n)\n```\n\n## `match` function continued\n\nArray's are matched as tuples, the lengths have to be the same:\n\n```typescript\nmatch([1, 2, 3]\n      when([1, 2], () =\u003e \"this won't match\"),\n      when([1, 2, 3], () =\u003e \"this will match\"))\n\"this will match\"\n```\n\nThe tail of a list can be matched with `__.rest`, or it's aliases\n`__.tail` or `__.tl`:\n\n```typescript\nmatch(\n  range(50, 100),\n  when([50, 51, __.rest], () =\u003e 'this will match'),\n)\n;('this will match')\n```\n\nPrimitive types can be matched with special operators:\n\n```typescript\nconst thingy: {\n  data: {\n    someNumber: 1\n    metadata: { foobar: 'foobar' }\n    someOtherProp: {}\n  }\n  list: [1, 2, 3]\n}\n\nmatch(\n  thingy,\n  when(\n    {\n      data: { someNumber: __.number, metadata: __.object },\n      list: [__, __.rest],\n    },\n    () =\u003e 'this will match',\n  ),\n)\n;('this will match')\n```\n\nYou can capture variables and use them on the right hand side of match, if you\nuse `when` the callback will be typed with all variable bindings:\n\n```typescript\nconst thingy: {\n  meta: {\n    type: 'contrived example',\n    x: 1,\n    y: 2,\n  },\n  data: {\n    a: {\n      b: {\n        c: {\n          d: {\n            message: 'hello world'\n            value: 42\n          }\n        }\n      }\n    }\n  }\n}\n\nmatch(thingy,\n      when({ meta: V('x'),\n         data: { a: { b: { c: { d: { value: V('y') } } } } }\n       }, (captures) =\u003e captures))\n{\n  x: {\n    type: 'contrived example',\n    x: 1,\n    x: 2,\n  }\n  y: 42\n}\n```\n\nVariable captures can also apply a pattern that must also match for the\ncase.\n\n```typescript\nimport { match, __, V } from \"pattern-matching\"\n\nconst checkout = {\n  object: \"list\",\n  data: [\n    {\n      id: \"li_1\",\n      object: \"item\",\n      ...\n    },\n    {...},\n    {...}\n  ]\n}\nmatch(value,\n      when( { object: 'list',\n          data: V('data')([\n            V('first')({ object: 'item' }),\n            __.rest\n          ])\n        }, (captures) =\u003e captures ))\n\n{\n  data: [\n    {\n      id: \"li_1\",\n      object: \"item\",\n      ...\n    },\n    {...},\n    {...}\n  ]\n  first: {\n    id: \"li_1\",\n    object: \"item\",\n    ...\n  },\n}\n```\n\n## TODOs\n\n- [ \\] Proper type inference right-hand-side of match case\n- [ \\] Exhaustive type check for match cases\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkendal%2Fmatch-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdkendal%2Fmatch-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdkendal%2Fmatch-ts/lists"}