{"id":13850718,"url":"https://github.com/gaku-sei/ts-json-decode","last_synced_at":"2025-10-08T00:33:19.864Z","repository":{"id":28439250,"uuid":"118381374","full_name":"gaku-sei/ts-json-decode","owner":"gaku-sei","description":"A library ensuring type safety when decoding JSON data inspired by Elm","archived":false,"fork":false,"pushed_at":"2023-01-03T15:15:27.000Z","size":1001,"stargazers_count":14,"open_issues_count":13,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-18T15:12:12.320Z","etag":null,"topics":["decoder","elm","json","type-safety","typescript"],"latest_commit_sha":null,"homepage":"http://gaku-sei.github.io/ts-json-decode","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/gaku-sei.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":"2018-01-21T22:58:41.000Z","updated_at":"2024-02-16T08:03:23.000Z","dependencies_parsed_at":"2023-01-14T08:49:16.746Z","dependency_job_id":null,"html_url":"https://github.com/gaku-sei/ts-json-decode","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaku-sei%2Fts-json-decode","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaku-sei%2Fts-json-decode/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaku-sei%2Fts-json-decode/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gaku-sei%2Fts-json-decode/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gaku-sei","download_url":"https://codeload.github.com/gaku-sei/ts-json-decode/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248166242,"owners_count":21058475,"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":["decoder","elm","json","type-safety","typescript"],"created_at":"2024-08-04T20:01:28.095Z","updated_at":"2025-10-08T00:33:14.846Z","avatar_url":"https://github.com/gaku-sei.png","language":"TypeScript","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"readme":"# TypeScript JSON Decode\n\n## What is it? Why does it matter?\n\n`ts-json-decode` is a lightweight library (no dependencies) that allows complex data and strings decoding.\n\nMost of front end applications must deal with data coming from, or going to, the outside.\nWhether these data are fetched from a server, retrieved from the local storage, or simply input by the user, they are all **unsafe**.\n\nIn TypeScript unsafe often means `any`, or, since TypeScript 3.0, `unknown`.\n\nFor example `JSON.parse` (which is widely used to parse data coming from a server) returns `any`.\nThe solution then, in order to keep the illusion of \"type safeness\" is to blindly cast this `any` value into the desired type.\nTypeScript will joyfully compile, the developer enjoys that fancy autocompletion feature offered by TypeScript, and everything seems to be fine.\nUntil the moment the data coming from the server changes.\n\nHere is a simple example using the `fetch` API:\n\n```TypeScript\ninterface Resource {\n  foo: string;\n  bar: number;\n}\n\nasync function fetchResource(): Promise\u003cResource\u003e {\n  const res = await fetch(\"https://my-server.com/resource\");\n\n  const data: Resource = await res.json();\n\n  return data;\n}\n```\n\nIf `https://my-server.com/resource` returns a resource that differs from the `Resource` interface, a runtime error will occur, and it could be hard to debug.\nThis can be a pragmatic, easy win, solution especially for tiny applications, with small, controlled, versioned, and slowly moving API, but scalability issues will araise quickly.\n\nThe target of `ts-json-decode` is to ensure type safeness with a simple yet complete API.\n\n```TypeScript\nimport { Decoder, decodeValue, num, object, str } from \"ts-json-decode\";\n\ninterface Resource {\n  bar: number;\n  foo: string;\n}\n\nconst decoder: Decoder\u003cResource\u003e = object({\n  bar: num,\n  foo: str,\n});\n\nasync function fetchResource(): Promise\u003cResource\u003e {\n  const res = await fetch(\"https://my-server.com/resource\");\n\n  const data = decodeValue(decoder, await res.json());\n\n  return data;\n}\n```\n\n`data` will automatically be a valid `Resource` object.\nIf something goes wrong, for instance if `foo` is missing, or if `bar` is a `string`, then an explicit error is thrown (and catchable with the `catch` method in the previous example).\n\n## Documentation\n\nA full documentation can be found [here](http://gaku-sei.github.io/ts-json-decode/docs).\n\n## API\n\n### Decoder runners\n\nA `Decoder` is a simple function that will validate a data against a schema.\nIn order to actually run the validation, two functions are provided: `decodeValue` and `decodeString`.\n\n```TypeScript\nimport { decodeString, decodeValue } from 'ts-json-decode';\n\nimport { decoder } from './myLibrary';\n\n// `decodeValue` will decode (and validate) any kind of data structure\nconst data = decodeValue(decoder, { foo: \"bar\" });\n// `decodeString` will parse and decode json stringified strings\nconst data = decodeString(decoder, '{ \"foo\": \"bar\" }');\n```\n\nIf the runner can't decode the provided string/value, an error is thrown.\nYou may easily wrap the code above in a `Promise` or an `Observable`.\n\n### Safe decoders\n\nAre considered \"safe\", decoders returning value whose type is a proper TypeScript type or interface, without extra checks. For example `str`, `num`, or `nil` are all \"safe\", since `string`, `number` and `null` types exist in TypeScript.\n\n```TypeScript\nimport { decodeString, nil, num, str } from \"ts-json-decoder\";\n\nconst nilValue = decodeString(nil, \"null\");\n\nconst numValue = decodeString(num, \"42\");\n\nconst strValue = decodeString(str, '\"foobar\"');\n```\n\n### Unsafe decoders\n\nAre considered \"unsafe\", decoders returning value that **cannot** be completely type checked by TypeScript, mainly because of the limitations of the current TypeScript type system.\n\nMost of the time, these decoders are strongly related to the concept of [dependent typing](https://en.wikipedia.org/wiki/Dependent_type).\nHopefully, this concept could arrive [one day](https://github.com/Microsoft/TypeScript/pull/21316#issuecomment-36019748) in TypeScript.\n\nThey include decoders such as `minLength` or `maxLength` validating strings' length, or `int` validating that a number is an integer.\n\n### Additional tools\n\nYou may also `map` or `compose` decoders, allowing complex data to be decoded/validated and transformed on the fly. A `field` decoder also exist when you just need to read one attribute of an object.\n\n```TypeScript\nimport { decodeString, map, str } from \"ts-json-decode\";\n\n// `decoder` has type `Decoder\u003cnumber\u003e` here\nconst decoder = map(({ length }) =\u003e length, str);\n\n// `length` equals 6\nconst length = decodeString(decoder, '\"foobar\"');\n```\n\nOr using `compose` and `map` as well:\n\n```TypeScript\nimport { decodeString, compose, num, object, str } from \"ts-json-decode\";\n\nconst decoder = compose(\n  map(({ length }) =\u003e length, str),\n  map(x =\u003e x ** 2, num),\n);\n\n// `squaredLength` equals 36\nconst squaredLength = decodeString(decoder, '\"foobar\"');\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgaku-sei%2Fts-json-decode","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgaku-sei%2Fts-json-decode","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgaku-sei%2Fts-json-decode/lists"}