|
1 |
| -# guard |
2 |
| -Type guards for typescript. |
| 1 | +<a href="https://www.typescriptlang.org/"> |
| 2 | + <img |
| 3 | + src="https://raw.githubusercontent.com/typescript-package/core/refs/heads/main/ts-package-barcode-logo-512.png" |
| 4 | + width="20%" |
| 5 | + title="@typescript-package/guard" |
| 6 | + /> |
| 7 | +</a> |
| 8 | + |
| 9 | +## typescript-package/guard |
| 10 | + |
| 11 | +Type-safe guards for guarding the value types in TypeScript. |
| 12 | + |
| 13 | +<!-- npm badge --> |
| 14 | +[![npm version][typescript-package-npm-badge-svg]][typescript-package-npm-badge] |
| 15 | +[![GitHub issues][typescript-package-badge-issues]][typescript-package-issues] |
| 16 | +[![GitHub license][typescript-package-badge-license]][typescript-package-license] |
| 17 | + |
| 18 | +<br> |
| 19 | + |
| 20 | +## Table of contents |
| 21 | + |
| 22 | +* [Installation](#installation) |
| 23 | +* [Api](#api) |
| 24 | +* [Benefits](#benefits) |
| 25 | +* [Type](#type) |
| 26 | + * [Enforce](#enforce) |
| 27 | + * [Indicate](#indicate) |
| 28 | + * [Check](#check) |
| 29 | + * [Guard](#guard) |
| 30 | + * [Narrow](#narrow) |
| 31 | + * [Summary](#summary) |
| 32 | +* [Git](#git) |
| 33 | + * [Commit](#commit) |
| 34 | + * [Versioning](#versioning) |
| 35 | +* [License](#license) |
| 36 | + |
| 37 | +## Installation |
| 38 | + |
| 39 | +```bash |
| 40 | +npm install @typescript-package/guard |
| 41 | +``` |
| 42 | + |
| 43 | +## Api |
| 44 | + |
| 45 | +```typescript |
| 46 | +import { |
| 47 | + // `guard` object. |
| 48 | + guard, |
| 49 | + |
| 50 | + // Prefixed `guard` functions. |
| 51 | + guardArray, |
| 52 | + guardBigInt, |
| 53 | + guardBoolean, |
| 54 | + guardClass, |
| 55 | + guardDate, |
| 56 | + guardDefined, |
| 57 | + guardFalse, |
| 58 | + guardFunction, |
| 59 | + guardInstance, |
| 60 | + guardKey, |
| 61 | + guardNull, |
| 62 | + guardNumber, |
| 63 | + guardNumberBetween, |
| 64 | + guardObject, |
| 65 | + guardObjectKey, |
| 66 | + guardObjectKeyIn, |
| 67 | + guardObjectKeys, |
| 68 | + guardObjectKeysIn, |
| 69 | + guardObjectSomeKeys, |
| 70 | + guardPrimitive, |
| 71 | + guardRegExp, |
| 72 | + guardString, |
| 73 | + guardStringIncludes, |
| 74 | + guardStringIncludesSome, |
| 75 | + guardStringLength, |
| 76 | + guardStringLengthBetween, |
| 77 | + guardSymbol, |
| 78 | + guardTrue, |
| 79 | + guardType, |
| 80 | + guardUndefined |
| 81 | +} from '@typescript-package/guard'; |
| 82 | +``` |
| 83 | + |
| 84 | +## Benefits |
| 85 | + |
| 86 | +Benefits of properly using the guards. |
| 87 | + |
| 88 | +1. Development, compile, and runtime **validation**. |
| 89 | + * Development-time **validation** ensures the developer can only provide a specific type through the static typing in the IDE. |
| 90 | + * Compile-time **validation** performs static analysis during compilation, ensuring no type violations are present in the code. |
| 91 | + * Runtime **validation** confirms the type of a value at runtime, useful when working with data from external sources (e.g., APIs, user inputs). |
| 92 | + |
| 93 | +2. Type-safe code. |
| 94 | + * **Validates** external or dynamic data at runtime. |
| 95 | + * **Ensures** developers write type-safe code. |
| 96 | + |
| 97 | +3. Error **reduction** and **prevention**. |
| 98 | + * **Error reduction** by combining static analysis and runtime checks. |
| 99 | + * **Error prevention** by combining runtime validation with compile-time type checks reducing the risk of runtime errors due to unexpected types. |
| 100 | + |
| 101 | +4. **Enhanced code clarity** by reducing ambiguity in data types. |
| 102 | + |
| 103 | +5. **Enhanced application reliability** by ensuring unvalidated data does not cause severe issues. |
| 104 | + |
| 105 | +6. **Type safety layer** by ensuring the handling of unexpected or invalid data. |
| 106 | + |
| 107 | +## Type |
| 108 | + |
| 109 | +### Enforce |
| 110 | + |
| 111 | +A type enforce uses static typing to ensure only allowed types can be passed, and uses TypeScript's compile-time static analysis to enforce correctness. |
| 112 | + |
| 113 | +**Role**: A development and compile-time type restrictor and enforcer. |
| 114 | +**Scope**: Development and compile-time. |
| 115 | +**Purpose**: |
| 116 | + |
| 117 | +* Development and compile-time type **restriction** and **enforcement**. |
| 118 | +* **Enforces** type restrictions during development (via IDE feedback) and compile-time. |
| 119 | +* **Ensures** that only values of the specified type can be used before runtime. |
| 120 | +* **Disallows** invalid types at development and compile-time, but doesn't perform runtime checks, that is performed in the type checking. |
| 121 | + |
| 122 | +Enforce | Restrict | Check | |
| 123 | +------- | -------- | ----- | |
| 124 | +v | v | x | |
| 125 | + |
| 126 | +Example: |
| 127 | + |
| 128 | +```typescript |
| 129 | +const acceptNumber = ( |
| 130 | + value: number // type enforce/restrict |
| 131 | +): void => { |
| 132 | + console.log(value); |
| 133 | +}; |
| 134 | + |
| 135 | +acceptNumber(42); // v Allowed |
| 136 | +acceptNumber("42"); // x Development and compile-time error |
| 137 | +``` |
| 138 | + |
| 139 | +### Indicate |
| 140 | + |
| 141 | +Indicates as an expression `value is type` the value is of the specified type resulting in a `boolean` type. |
| 142 | + |
| 143 | +Example: |
| 144 | + |
| 145 | +```typescript |
| 146 | +const isNumber = ( |
| 147 | + value: unknown |
| 148 | +): value is number // type indicate |
| 149 | +=> { |
| 150 | + return typeof value === "number"; // type check |
| 151 | +} // type check |
| 152 | +``` |
| 153 | + |
| 154 | +### Check |
| 155 | + |
| 156 | +Operate only at runtime, allowing validation of dynamically-typed or unknown values. |
| 157 | + |
| 158 | +**Role**: Runtime checker. |
| 159 | +**Scope**: Runtime only. |
| 160 | +**Purpose**: |
| 161 | + |
| 162 | +* **Checks** whether a given value is of a specific type during execution. |
| 163 | +* Used to create the type narrow. |
| 164 | + |
| 165 | +Enforce | Restrict | Check | |
| 166 | +------- | -------- | ----- | |
| 167 | +x | x | v | |
| 168 | + |
| 169 | +### Guard |
| 170 | + |
| 171 | +Combine development, and compile-time restriction with runtime validation, ensures the value type matches the expected type on any time, ensuring stricter enforcement of types. |
| 172 | + |
| 173 | +**Role**: A development, compile, and run-time type restrictor and enforcer. |
| 174 | +**Scope**: Development, compile, and run-time. |
| 175 | +**Purpose**: |
| 176 | + |
| 177 | +* **Ensures** the developer can only provide a specific type through the static typing. |
| 178 | +* **Enforces** type restrictions during development (via IDE feedback) and compile-time. |
| 179 | +* **Checks** whether a given value is of a specific type during execution. |
| 180 | + |
| 181 | +Enforce | Restrict | Check | |
| 182 | +------- | -------- | ----- | |
| 183 | +v | v | v | |
| 184 | + |
| 185 | +Example: |
| 186 | + |
| 187 | +```typescript |
| 188 | +const guardNumber = ( |
| 189 | + value: number // type enforce |
| 190 | +): value is number // type indicator |
| 191 | +=> { |
| 192 | + return typeof value === "number"; // type check |
| 193 | +} // overall type guard |
| 194 | +``` |
| 195 | + |
| 196 | +### Narrow |
| 197 | + |
| 198 | +It's a type-guard that ensures the narrowed type of a value matches the expected type on runtime. |
| 199 | + |
| 200 | +**Role**: A development, compile, and run-time type narrower. |
| 201 | +**Scope**: Development, compile-time, and runtime. |
| 202 | +**Purpose**: |
| 203 | + |
| 204 | +* Compile-time **restriction** and **enforcement**. |
| 205 | +* **Reduces** or **refines** the possible types of a value within a specific scope. |
| 206 | +* **Enables** precise typing based on context, such as conditional checks or type guards, affecting behavior at development, compile, and runtime. |
| 207 | + |
| 208 | +Enforce | Restrict | Narrow | |
| 209 | +------- | -------- | ------ | |
| 210 | +v | v | v | |
| 211 | + |
| 212 | +Example: |
| 213 | + |
| 214 | +```typescript |
| 215 | +const processValue = ( |
| 216 | + value: string | number // type enforce |
| 217 | +): void => { |
| 218 | + if (typeof value === "string") { |
| 219 | + console.log(value.toUpperCase()); // Type narrowed to 'string' |
| 220 | + } else { |
| 221 | + console.log(value.toFixed(2)); // Type narrowed to 'number' |
| 222 | + } |
| 223 | +}; // type narrow |
| 224 | + |
| 225 | +processValue(42); // v Logs: 42.00 |
| 226 | +processValue("hello"); // v Logs: HELLO |
| 227 | +``` |
| 228 | + |
| 229 | +> It looks at these special checks (called type guards) and assignments, and the process of refining types to more specific types than declared is called narrowing. ["Typescript"](https://www.typescriptlang.org/docs/handbook/2/narrowing.html) |
| 230 | +
|
| 231 | +### Summary |
| 232 | + |
| 233 | +Time scope. |
| 234 | + |
| 235 | +Feature | Development-time | Compile-time | Runtime | |
| 236 | +-------- | ---------------- | ------------ | ------- | |
| 237 | +Enforce | v | v | x | |
| 238 | +Indicate | v | x | x | |
| 239 | +Check | x | x | v | |
| 240 | +Guard | v | v | v | |
| 241 | +Narrow | v | v | v | |
| 242 | + |
| 243 | +## GIT |
| 244 | + |
| 245 | +### Commit |
| 246 | + |
| 247 | +* [AngularJS Git Commit Message Conventions][git-commit-angular] |
| 248 | +* [Karma Git Commit Msg][git-commit-karma] |
| 249 | +* [Conventional Commits][git-commit-conventional] |
| 250 | + |
| 251 | +### Versioning |
| 252 | + |
| 253 | +[Semantic Versioning 2.0.0][git-semver] |
| 254 | + |
| 255 | +**Given a version number MAJOR.MINOR.PATCH, increment the:** |
| 256 | + |
| 257 | +* MAJOR version when you make incompatible API changes, |
| 258 | +* MINOR version when you add functionality in a backwards-compatible manner, and |
| 259 | +* PATCH version when you make backwards-compatible bug fixes. |
| 260 | + |
| 261 | +Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format. |
| 262 | + |
| 263 | +**FAQ** |
| 264 | +How should I deal with revisions in the 0.y.z initial development phase? |
| 265 | + |
| 266 | +> The simplest thing to do is start your initial development release at 0.1.0 and then increment the minor version for each subsequent release. |
| 267 | +
|
| 268 | +How do I know when to release 1.0.0? |
| 269 | + |
| 270 | +> If your software is being used in production, it should probably already be 1.0.0. If you have a stable API on which users have come to depend, you should be 1.0.0. If you’re worrying a lot about backwards compatibility, you should probably already be 1.0.0. |
| 271 | +
|
| 272 | +## License |
| 273 | + |
| 274 | +MIT © typescript-package ([license][typescript-package-license]) |
| 275 | + |
| 276 | +<!-- This package: typescript-package --> |
| 277 | + <!-- GitHub: badges --> |
| 278 | + [typescript-package-badge-issues]: https://img.shields.io/github/issues/typescript-package/guard |
| 279 | + [isscript-package-badge-forks]: https://img.shields.io/github/forks/typescript-package/guard |
| 280 | + [typescript-package-badge-stars]: https://img.shields.io/github/stars/typescript-package/guard |
| 281 | + [typescript-package-badge-license]: https://img.shields.io/github/license/typescript-package/guard |
| 282 | + <!-- GitHub: badges links --> |
| 283 | + [typescript-package-issues]: https://github.com/typescript-package/guard/issues |
| 284 | + [typescript-package-forks]: https://github.com/typescript-package/guard/network |
| 285 | + [typescript-package-license]: https://github.com/typescript-package/guard/blob/master/LICENSE |
| 286 | + [typescript-package-stars]: https://github.com/typescript-package/guard/stargazers |
| 287 | +<!-- This package --> |
| 288 | + |
| 289 | +<!-- Package: typescript-package --> |
| 290 | + <!-- npm --> |
| 291 | + [typescript-package-npm-badge-svg]: https://badge.fury.io/js/@typescript-package%2Fguard.svg |
| 292 | + [typescript-package-npm-badge]: https://badge.fury.io/js/@typescript-package%2Fguard |
| 293 | + |
| 294 | +<!-- GIT --> |
| 295 | +[git-semver]: http://semver.org/ |
| 296 | + |
| 297 | +<!-- GIT: commit --> |
| 298 | +[git-commit-angular]: https://gist.github.com/stephenparish/9941e89d80e2bc58a153 |
| 299 | +[git-commit-karma]: http://karma-runner.github.io/0.10/dev/git-commit-msg.html |
| 300 | +[git-commit-conventional]: https://www.conventionalcommits.org/en/v1.0.0/ |
0 commit comments