{"id":23380549,"url":"https://github.com/flix-tech/fp-ts-type-check","last_synced_at":"2025-04-10T22:42:45.378Z","repository":{"id":53082764,"uuid":"285007676","full_name":"flix-tech/fp-ts-type-check","owner":"flix-tech","description":"runtime type validation library for Typescript","archived":false,"fork":false,"pushed_at":"2021-04-07T13:42:39.000Z","size":81,"stargazers_count":15,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-17T22:56:47.805Z","etag":null,"topics":["hacktoberfest","parsers","typescript"],"latest_commit_sha":null,"homepage":"","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/flix-tech.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}},"created_at":"2020-08-04T14:38:52.000Z","updated_at":"2022-11-22T19:53:21.000Z","dependencies_parsed_at":"2022-09-08T16:51:07.194Z","dependency_job_id":null,"html_url":"https://github.com/flix-tech/fp-ts-type-check","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flix-tech%2Ffp-ts-type-check","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flix-tech%2Ffp-ts-type-check/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flix-tech%2Ffp-ts-type-check/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flix-tech%2Ffp-ts-type-check/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flix-tech","download_url":"https://codeload.github.com/flix-tech/fp-ts-type-check/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248312208,"owners_count":21082638,"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":["hacktoberfest","parsers","typescript"],"created_at":"2024-12-21T20:16:44.606Z","updated_at":"2025-04-10T22:42:45.352Z","avatar_url":"https://github.com/flix-tech.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"fp-ts-type-check is a library for runtime type validation of variables where you can't say their type for sure i.e. data you get via some API. It's somewhat similar to Typescript's [Type Guards](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards) except it uses type system to make sure this data is properly validated.\n\nFeatures:\n\n* **Type safe.** Typescript compiler makes sure your types and your type checkers are always in sync.\n* **Detailed error reports.** If parsing of a big deep-nested structure failed - you'll know where exactly in that structure you have invalid data and why it was considered invalid\n* **Composable.** Type checkers for big structures are created by composing checkers for simple structures. \n* **Functional.** Each type checker is a pure function returning `Either` type from fp-ts. It's up for you to decide how to handle errors.\n* **[Tree-shakeable](https://webpack.js.org/guides/tree-shaking/).** Bundle only functions you really use.\n\n## Installation\n\nTo install the stable version:\n\n```\nnpm install '@flix-tech/fp-ts-type-check@~0.2.0'\n```\n\nWhile the major version number is 0 changes in minor version number bay break backward compatibility so you should stick to a fixed minor version.\n\n## Usage\n\nMeet `Parser[T]`, the main type of this library. `Parser[T]` is a function that takes any variable and checks if it's a variable of type `T`. It either returns the same value as `T` or `ParseError` object with parse error details. Parser's type definition looks somewhat like this:\n\n```typescript\ntype Parser\u003cA\u003e = (x: unknown): Either\u003cParseError, A\u003e;\n\ninterface ParseError {\n  path: string; // Path to the property causing error in deep nested structures\n  message: string; // Parsing error message\n}\n```\n\nWe're using the type [Either](https://gcanti.github.io/fp-ts/modules/Either.ts.html) from [fp-ts](https://github.com/gcanti/fp-ts) library.\n\nParsers for some complex structures you'd want to validate are composed from small parsers like here:\n\n```typescript\nimport * as P from 'fp-ts-type-check';\n\ninterface ShoppingListItem {\n  name: string;\n  amount: { count: number; unit?: string };\n}\nconst shoppingListItemParser: P.Parser\u003cShoppingListItem\u003e = P.type({\n  name: P.string,\n  amount: P.type({\n    count: P.number,\n    unit: P.optional(P.string),\n  }),\n});\n\nshoppingListItem({name: \"Apple\", amount: {count: 5}}); // Right\u003cShoppingListItem\u003e({name: \"Apple\", amount: {count: 5}})\n\nshoppingListItem({name: \"Apple\", amount: {count: \"some\"}}); // Left\u003cParseError\u003e({path: \".amount.count\", message: \"expected number, got string\"})\n```\n\nAs you can see, `ParseError` data is for your eyes only, user should get a generalized error message appropriate in this case.\n\nYou can reuse your parsers to construct parsers for even bigger structures:\n\n```typescript\ntype ShoppingList = array\u003cShoppingListItem\u003e;\n\nconst shoppingListParser: P.Parser\u003cShoppingList\u003e = P.arrayOf(shoppingListItemParser);\n\nconst validShoppingList = [\n  {name: \"Apple\", amount: {count: 5}},\n  {name: \"Milk\", amount: {count: 500, unit: 'ml'}},\n];\nshoppingListParser(validShoppingList); // Right\u003cShoppingList\u003e(...)\n\nconst invalidShoppingList = [\n  {name: \"Apple\", amount: {count: 5}},\n  {name: \"Milk\", amount: {unit: 'ml'}}, // No count here\n];\nshoppingListParser(invalidShoppingList); // Left\u003cParseError\u003e({path: \"[1].amount.count\", message: \"expected number, got undefined\"})\n```\n\n# API documentation\n\n### Simple type parsers\n\n* `string(): Parser\u003cstring\u003e` - checks that value is string.\n* `boolean(): Parser\u003cboolean\u003e` - checks that value is boolean.\n* `number(): Parser\u003cnumber\u003e` - checks that value is number.\n* `object(): Parser\u003cobject\u003e` - checks that value is any object.\n* `any(): Parser\u003cany\u003e` - does not check anything.\n* `exact\u003cA\u003e(expected: A): Parser\u003cA\u003e` - checks that value is same as expected one.\n* `oneOf\u003cA\u003e(allowed: A[]): Parser\u003cA\u003e` - checks that value is one of allowed ones.\n* `keyOf\u003cA extends object\u003e(allowed: A): Parser\u003ckeyof A\u003e` - checks that value is string and also is a key of object `allowed`.\n\n## Copositional parsers\n\n* `type\u003cA\u003e(propertyParsers: { [K in keyof A]: Parser\u003cA[K]\u003e }): Parser\u003cA\u003e` - checks that values is an object and validates each it's property with corresponding parser.\n\n* `arrayOf\u003cA\u003e(parseBody: Parser\u003cA\u003e): Parser\u003cA[]\u003e` - checks that value is an array and every item matches  `parseBody` parser.\n\n* `optional\u003cA\u003e(parseBody: Parser\u003cA\u003e): Parser\u003cA | undefined\u003e` - checks that value is either undefined or matches `parseBody` parser.\n\n* `nullable\u003cA\u003e(parseBody: Parser\u003cA\u003e): Parser\u003cA | null\u003e` - checks that value is either null or matches `parseBody` parser.\n\n* `discriminatedUnion\u003cA extends {type: string;}\u003e(parsers: {(type value): (type parser)}): Parser\u003cA\u003e` - checks that value is a [discriminated union](https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions) with discriminant in `type` property. Example usage:\n\n  ```typescript\n  type Foo = { type: 'foo'; foo: number };\n  type Bar = { type: 'bar'; bar: number };\n  type FooBar = Foo | Bar;\n  \n  const parser: P.Parser\u003cFooBar\u003e = P.discriminatedUnion({\n    foo: P.type({ foo: P.number }),\n    bar: P.type({ bar: P.number }),\n  });\n  ```\n\n### Logic combination parsers\n\n* `and(parserA: Parser\u003cA\u003e, parserB\u003cB\u003e): Parser\u003cA \u0026 B\u003e` - checks that value matches both types A and B.\n* `or(parserA: Parser\u003cA\u003e, parserB\u003cB\u003e): Parser\u003cA | B\u003e` - checks that value matches any of types A or B.\n\n## License\n\nThe MIT License (MIT)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflix-tech%2Ffp-ts-type-check","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflix-tech%2Ffp-ts-type-check","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflix-tech%2Ffp-ts-type-check/lists"}