{"id":42988408,"url":"https://github.com/madonoharu/ts-norm","last_synced_at":"2026-01-31T02:33:43.566Z","repository":{"id":57157312,"uuid":"437139483","full_name":"madonoharu/ts-norm","owner":"madonoharu","description":"A normalizr like library for TypeScrip","archived":false,"fork":false,"pushed_at":"2022-03-30T14:41:23.000Z","size":182,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2024-08-21T20:07:14.437Z","etag":null,"topics":["denormalize","normalize","normalizr","redux","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/madonoharu.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":"2021-12-10T23:20:22.000Z","updated_at":"2023-10-24T15:56:11.000Z","dependencies_parsed_at":"2022-09-07T18:32:27.647Z","dependency_job_id":null,"html_url":"https://github.com/madonoharu/ts-norm","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/madonoharu/ts-norm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madonoharu%2Fts-norm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madonoharu%2Fts-norm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madonoharu%2Fts-norm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madonoharu%2Fts-norm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/madonoharu","download_url":"https://codeload.github.com/madonoharu/ts-norm/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madonoharu%2Fts-norm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28927223,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T22:32:35.345Z","status":"online","status_checked_at":"2026-01-31T02:00:09.179Z","response_time":128,"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":["denormalize","normalize","normalizr","redux","typescript"],"created_at":"2026-01-31T02:33:43.477Z","updated_at":"2026-01-31T02:33:43.548Z","avatar_url":"https://github.com/madonoharu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ts-norm\n\n[![npm version](https://img.shields.io/npm/v/ts-norm?style=flat-square)](https://www.npmjs.com/package/ts-norm)\n\nA [normalizr](https://github.com/paularmstrong/normalizr) like library for TypeScript.  \n🙏Pull requests are welcome!\n\n## Installation\n\n```shell\nyarn add ts-norm\n```\n\n```shell\nnpm install ts-norm\n```\n\n## Quick Start\n\nConsider a typical blog post. The API response for a single post might look something like this:\n\n```json\n{\n  \"id\": \"123\",\n  \"author\": {\n    \"id\": \"1\",\n    \"name\": \"Paul\"\n  },\n  \"title\": \"My awesome blog post\",\n  \"comments\": [\n    {\n      \"id\": \"324\",\n      \"commenter\": {\n        \"id\": \"2\",\n        \"name\": \"Nicole\"\n      }\n    }\n  ]\n}\n```\n\nWe have two nested entity types within our `article`: `users` and `comments`. Using various `schema`, we can normalize all three entity types down:\n\n```ts\nimport { normalize, denormalize, schema, Dictionary } from \"ts-norm\";\n\ntype User = {\n  id: string;\n  name: string;\n};\ntype Comment = {\n  id: string;\n  commenter: User;\n};\ntype Article = {\n  id: string;\n  author: User;\n  title: string;\n  comments: Comment[];\n};\n\n// Define a users schema\nconst user = schema\u003cUser\u003e().entity(\"users\");\n\n// Define your comments schema\nconst comment = schema\u003cComment\u003e().entity(\"comments\", {\n  commenter: user,\n});\n\n// Define your article\nconst article = schema\u003cArticle\u003e().entity(\"articles\", {\n  author: user,\n  comments: [comment],\n});\n\nconst normalizedData = normalize(originalData, article);\nconst denormalizedData = denormalize(\n  normalizedData.result,\n  article,\n  normalizedData.entities\n);\n\ntype Expected = {\n  result: string;\n  entities: {\n    users: Dictionary\u003c{ id: string; name: string }\u003e;\n    comments: Dictionary\u003c{ id: string; commenter: string }\u003e;\n    articles: Dictionary\u003c{\n      id: string;\n      author: string;\n      title: string;\n      comments: string[];\n    }\u003e;\n  };\n};\n\n// Type Safe!!\nfunction expectType\u003cT\u003e(_: T) {}\nexpectType\u003cExpected\u003e(normalizedData);\nexpectType\u003cArticle\u003e(denormalizedData);\n```\n\nNow, `normalizedData` will be:\n\n```json\n{\n  \"result\": \"123\",\n  \"entities\": {\n    \"articles\": {\n      \"123\": {\n        \"id\": \"123\",\n        \"author\": \"1\",\n        \"title\": \"My awesome blog post\",\n        \"comments\": [\"324\"]\n      }\n    },\n    \"users\": {\n      \"1\": { \"id\": \"1\", \"name\": \"Paul\" },\n      \"2\": { \"id\": \"2\", \"name\": \"Nicole\" }\n    },\n    \"comments\": {\n      \"324\": { \"id\": \"324\", \"commenter\": \"2\" }\n    }\n  }\n}\n```\n\n## With `idAttribute` \u0026 `generateId`\n\n```ts\ntype User = {\n  name: string;\n};\ntype Article = {\n  title: string;\n  author: User;\n};\n\nconst user = schema\u003cUser\u003e().entity(\n  \"users\",\n  {},\n  {\n    idAttribute: \"userId\",\n    generateId: (): string =\u003e uuid(),\n  }\n);\nconst article = schema\u003cArticle\u003e().entity(\n  \"articles\",\n  { author: user },\n  {\n    idAttribute: \"articleId\",\n    generateId: (): number =\u003e counter(),\n  }\n);\n\nconst normalizedData = normalize(originalData, article);\n\ntype Expected = {\n  result: number;\n  entities: {\n    users: Dictionary\u003c{\n      userId: string;\n      name: string;\n    }\u003e;\n    articles: Dictionary\u003c{\n      articleId: number;\n      title: string;\n      author: string;\n    }\u003e;\n  };\n};\n\nfunction expectType(_: Expected) {}\nexpectType(normalizedData);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadonoharu%2Fts-norm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmadonoharu%2Fts-norm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadonoharu%2Fts-norm/lists"}