{"id":23168893,"url":"https://github.com/toreda/strong-types","last_synced_at":"2025-08-18T06:33:55.476Z","repository":{"id":46059511,"uuid":"293385032","full_name":"toreda/strong-types","owner":"toreda","description":"Automated type checks and guaranteed return types with 1 line of code. Say goodbye to reference errors from unexpected types. Write less validation code and improve quality.","archived":false,"fork":false,"pushed_at":"2022-12-04T10:28:00.000Z","size":1699,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-12T22:41:10.974Z","etag":null,"topics":["data-structures","strong-types","type-safe","type-safety","type-system"],"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/toreda.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-09-07T00:27:55.000Z","updated_at":"2022-04-28T18:00:48.000Z","dependencies_parsed_at":"2023-01-24T03:16:06.945Z","dependency_job_id":null,"html_url":"https://github.com/toreda/strong-types","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toreda%2Fstrong-types","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toreda%2Fstrong-types/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toreda%2Fstrong-types/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/toreda%2Fstrong-types/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/toreda","download_url":"https://codeload.github.com/toreda/strong-types/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230210444,"owners_count":18190671,"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":["data-structures","strong-types","type-safe","type-safety","type-system"],"created_at":"2024-12-18T03:14:06.499Z","updated_at":"2024-12-18T03:14:52.468Z","avatar_url":"https://github.com/toreda.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `@toreda/strong-types`\n\n![CI](https://github.com/toreda/strong-types/workflows/CI/badge.svg?branch=master) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=toreda_strong-types\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=toreda_strong-types) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=toreda_strong-types\u0026metric=alert_status)](https://sonarcloud.io/dashboard?id=toreda_strong-types)\n\nNative TypeScript containers for generic value storage. Reliably store and retrieve typed values without writing validation or type checking code. Use [built-in types](#BuiltInTypes) or define your own.\n\n\nWhat does it do?\n```typescript\nimport {StrongInt, makeInt} from '@toreda/strong-types';\n//  int with initial value 10.\nconst int = makeInt(10, 0);\n// Prints 10. It always return an int.\nconsole.log(int());\n\n// Set the value\nint(11);\n// Prints 11.\nconsole.log(int());\n\n// Won't set the value - it's not an int.\nint(null);\nint(undefined);\nint(3.33);\nint({});\n\n// Prints 11\nconsole.log(int());\n```\n# Contents\n\n* [**Basic Usage**](#basic-usage)\n*\t[**Built-in Types**](#built-in-types)\n\t  - [`StrongMap`](#StrongMap)\n\t  -\t[`StrongArray`](#StrongArray)\n\t  - [`StrongBoolean`](#StrongBoolean)\n\t  - [`StrongDouble`](#StrongDouble)\n\t  - [`StrongInt`](#StrongInt)\n\t  - [`StrongStrongring`](#StrongStrongring)\n\t  - [`StrongUInt`](#StrongUInt)\n*\t[**Custom Types**](#custom-types)\n\t  - [Validators](#validators)\n* \t[**Package**](#package)\n\t-\t[Build](#build)\n\t-\t[Testing](#testing)\n\t-   [License](#license)\n\n\n# Using `StrongType`\n\nEach built-in type exports a type and make function. The below examples use StrongInt but work the same using: `StrongArray`, `StrongBoolean`, `StrongDouble`, `StrongInt`, `StrongString`, and `StrongUInt`.\n\n## Instantiate with initial value\n```typescript\nimport {StrongInt, makeInt} from '@toreda/strong-types';\n\nconst initial = 11;\nconst fallback = 55;\nconst int = makeInt(initial, fallback);\n\n// Returns 11 - initial value was 11.\nconst value = int();\n```\n\n## Instantiate without initial value\n\n\n\n```typescript\nimport {StrongInt, makeInt} from '@toreda/strong-types';\n\nconst fallback = 919;\nconst int = makeInt(null, fallback);\n\n// value is 919 - initial value was null, so fallback was\n// returned instead to maintain the function's return type guarantee.\nconst value = int();\n```\n\n## Get with Fallback\n* `get(fallback: T): T`\nCall `container.get(fallback)` when a per-call fallback is preferred instead of the container's default fallback.\n```typescript\nimport {StrongInt, makeInt} from '@toreda/strong-types';\nconst int = makeInt(null, 555);\n\nconst fallback = 331;\n// Prints 331 (fallback) instead of 555 (container default fallback).\nconsole.log(value.get(fallback));\n```\n\n## GetNull\n* `getNull(): T | null`\nCall `container.getNull()` to the current value, even if null. Value will never be undefined and will always return either null, or a value of container's generic type T. \n\nNOTE: `getNull` **DOES NOT** take a fallback argument and will not return the container's default fallback. It always returns value (`null` or `StrongType\u003cT\u003e`).\n\n```typescript\nimport {StrongInt, makeInt} from '@toreda/strong-types';\n\nconst fallback = 919;\nconst int = makeInt(null, fallback);\n\n// Prints null. Default fallback is not used for `getNull` calls.\nconsole.log(int.getNull());\n```\n\n## Set Value\n```\nimport {StrongInt, makeInt} from '@toreda/strong-types';\n\nconst initial = 331;\nconst fallback = 400;\nconst int = makeInt(initial, fallback);\n\n// value is 331 - the int's initial value.\nconst value = int();\n\n// Set int to a new value.\nint(555);\n\n// value is 555 - the value we updated int to.\nconst value = int();\n\n```\n\n## Set `null`\n```typescript\nimport {StrongInt, makeInt} from '@toreda/strong-types';\n\nconst initial = 414;\nconst fallback = 500;\nconst int = makeInt(initial, fallback);\n\n// value is 414 - the int's initial value.\nconst value = int();\n\n\n// Set value to null.\nint(null);\n\n// value is 500 - Fallback returned because value was null.\nconst value = int();\n\n```\n\n## Reset Value\n\nCall `myContainer.reset()` to reset value without creating a new StrongType container. Default Fallback will not be reset. Useful for unit testing and serverless environments where the previous container value or state is unknown.\n\n```typescript\nimport {StrongInt, makeInt} from '@toreda/strong-types';\n\nconst initial = 515;\nconst fallback = 600;\nconst int = makeInt(initial, fallback);\n\n// value is 515 (the initial value).\nconst value = int();\n\n// Reset container value\nint.reset();\n\n// Prints 600 (fallback). value was reset to null,\n// fallback was returned to maintain return type guarantee.\nconsole.log(int());\n\n```\n\n### Validation\n`StrongType` containers validate value inputs before setting. Bad values are ignored and will not cause a throw. Each built-in container type provides specific guarantees for which values are allowed.\n\n```typescript\nimport {StrongInt, makeInt} from '@toreda/strong-types';\nconst int = makeInt(50, 100);\n\n// success is false.\n// container.value is still it's initial value 50 because 1.5 is not an int.\n// StrongInt does not round or truncate non-integers. They are simply ignored.\nconst success = int(1.5);\n```\n\n\n# Supported Types\n* [`StrongArray`](#StrongArray), arrays\n* [`StrongBoolean`](#StrongBoolean), booleans (strict)\n* [`StrongDouble`](#StrongDouble), doubles\n* [`StrongInt`](#StrongInt), integers\n* [`StrongUInt`](#StrongUint), unsigned integers\n* [`StrongString`](#StrongString) - strings\n\n# Using `StrongMap`\n\nCreating and using a StrongMap class.\n```typescript\nimport {StrongMap, StrongInt, StrongString, makeInt, makeString} from '@toreda/strong-types';\n\n\nexport class SomeConfig extends StrongMap {\n\tpublic readonly counter: StrongInt;\n\tpublic readonly name: StrongString;\n\n\tconstructor(json: any) {\n\t\tsuper();\n\t\tthis.counter = makeInt(0, 0);\n\t\tthis.name = makeString(null, 'TreeBeard');\n\t\tthis.parse(json);\n\t}\n}\n\n\n// Use it\nconst myConfig = new SomeConfig();\n\n// Prints '0'\nconsole.log(myConfig.counter());\n\n// Prints 'Treebeard'\nconsole.log(myConfig.name());\n```\n\nCreating a `StrongMap` and loading values from JSON\n```typescript\nimport {StrongMap, StringInt, StrongString, makeInt, makeString} from '@toreda/strong-types';\n\nexport class SomeConfig extends StrongMap {\n\tpublic readonly counter: StrongInt;\n\tpublic readonly name: StrongString;\n\n\tconstructor(json?: any) {\n\t\tsuper();\n\t\tthis.counter = makeInt(0, 0);\n\t\tthis.name = makeString(null, 'TreeBeard');\n\t\tthis.parse(json);\n\t}\n}\n\nconst myJSON = {\n\t'counter': 99,\n\t'name': 'Sauron'\n};\n\n// Load the recursively parse a JSON object.\nconst myConfig = new SomeConfig(myJSON);\n\n// Prints 99 - myJSON.counter was loaded into SomeConfig.counter at instantiation.\nconsole.log(myConfig.counter());\n\n// Prints 'Sauron' - myJSON.name was loaded into SomeConfig.name at instantiation.\nconsole.log(myConfig.name());\n```\n\nConverting a `StrongMap` to a json object\n```typescript\nimport {StrongMap, StringInt, StrongString, makeInt, makeString} from '@toreda/strong-types';\n\nexport class SomeConfig extends StrongMap {\n\tpublic readonly counter: StrongInt;\n\tpublic readonly name: StrongString;\n\n\tconstructor(json?: any) {\n\t\tsuper();\n\t\tthis.counter = makeInt(0, 0);\n\t\tthis.name = makeString(null, 'TreeBeard');\n\t\tthis.parse(json);\n\t}\n}\n\nconst myJSON = {\n\t'counter': 99,\n\t'name': 'Sauron'\n};\n\n// Create the StrongMap with myJSON data\nconst myConfig = new SomeConfig(myJSON);\n\n// Change a value in the StrongMap\nmyConfig.name('Gandalf');\n\n// {counter: 99, name: 'Gandalf'}\nconst configAsJSON = myConfig.jsonify();\n```\n\n## `StrongArray`\n\n### Import\n\n```typescript\nimport {StrongArray, makeArray} from '@toreda/strong-types';\n```\n\n### Accepted Values\n* Arrays holding any type (e.g. `T[]`)\n* Accepts empty arrays (e.g. `[]`)\n\n\n## `StrongBoolean`\n\n### Import\n```typescript\nimport {StrongBoolean, makeBoolean} from '@toreda/strong-types';\n```\n\n### Accepted Values\n* Strict booleans: `true` or `false` only.\n* No type coercion (e.g. `1` or `0` will be rejected).\n\n## `StrongDouble`\n\n### Import\n```typescript\nimport {StrongDouble, makeDouble} from '@toreda/strong-types';\n```\n\n### Accepted Values\n* `number` values between and including Number.MIN_VALUE and Number.MAX_VALUE.\n* Rejects `NaN` values.\n\n## `StrongInt`\n\n### Import ###\n```typescript\nimport {StrongInt, makeInt} from '@toreda/strong-types';\n```\n### Accepted Values ###\n* `number` values between and including Number.MIN_VALUE and Number.MAX_VALUE.\n* `NaN` values are rejected.\n\n\n## `StrongString`\n\n### Import\n```typescript\nimport {StrongString, makeString} from '@toreda/strong-types';\n```\n### Accepted Values ###\n* `string` values of any valid length.\n\n\n## `StrongUInt`\n\n### Import\n```typescript\nimport {StrongUInt, makeUInt} from '@toreda/strong-types';\n```\n\n### Accepted Values ###\n* Integers between and including 0 and `Number.MAX_SAFE_INTEGER`.\n* Rejects numbers which are non-integers (e.g. `1.5`)\n* Rejects `NaN`\n* Rejected negative integers (e.g. `-22`).\n\n# Custom Types\nEach built-in type like `StrongInt` and `StrongUInt` are helper functions wrapping `StrongType\u003cT\u003e`. They also apply validators which guarantee the `StrongType\u003cT\u003e` value behaves as expected. While built-ins are provided for convenience, you can create custom types with your own validators.\n\n## Instantiate `StrongType\u003cT\u003e`\n\n```typescript\nimport {StrongType, makeStrong} from '@toreda/strong-types';\n\nexport type MyOwnType = {\n\tid: string | null;\n\tname: string | null;\n};\n\nconst initial: MyOwnType = {\n\tid: 'hello',\n\tname: 'my name is'\n};\n\nconst fallback: MyOwnType = {\n\tid: null,\n\tname: null\n};\n\nconst myObj = makeStrong\u003cMyOwnType\u003e(initial, fallback);\n\n```\n\n## Validators\n\n\n# Install\nInstall `@toreda/strong-types` directly from NPM or [clone the Github repo](https://github.com/toreda/strong-types).\n\n### Install using Yarn (preferred)\n 1. Open a shell (or console).\n 2. Navigate to the the StrongTypes root project folder.\n 3. Enter the following commands in order. Wait for each to complete before typing the next.\n```bash\nyarn\n```\n\n### Install using NPM\n 1. Open a shell (or console).\n 2. Navigate to the the StrongTypes root project folder.\n 3. Enter the following commands in order. Wait for each to complete before typing the next.\n```bash\nnpm install\n```\n\n\n# Run Unit Tests\nInstall or clone StrongTypes [(see above)](#install).\n\nStrongTypes tests are written with [Jest](https://jestjs.io/) which is also a project dev dependency.\n\nInstalling jest is not required after project dependencies are installed ([see above](#install)).\n```bash\nyarn test\n```\n\n# Build from source\n\nThe next steps are the same whether you installed the package using NPM or cloned the repo from Github.\n\n### Build with Yarn\n Enter the following commands in order from the StrongTypes root project folder.\n```bash\nyarn build\n```\n\n### Build with NPM\n Enter the following commands in order from the StrongTypes root project folder.\n```bash\nnpm run-script build\n```\n\n# License\n\n[MIT](LICENSE) \u0026copy; Toreda, Inc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoreda%2Fstrong-types","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftoreda%2Fstrong-types","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoreda%2Fstrong-types/lists"}