Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sniptt-official/guards
🛡 Comprehensive collection of type guards for JavaScript and TypeScript; Inspired by Elixir
https://github.com/sniptt-official/guards
deno elixir erlang javascript nodejs type-guards type-safety typescript
Last synced: 6 days ago
JSON representation
🛡 Comprehensive collection of type guards for JavaScript and TypeScript; Inspired by Elixir
- Host: GitHub
- URL: https://github.com/sniptt-official/guards
- Owner: sniptt-official
- License: mit
- Created: 2020-06-03T15:41:22.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2023-03-04T22:04:17.000Z (almost 2 years ago)
- Last Synced: 2024-12-07T11:41:37.005Z (15 days ago)
- Topics: deno, elixir, erlang, javascript, nodejs, type-guards, type-safety, typescript
- Language: TypeScript
- Homepage:
- Size: 805 KB
- Stars: 173
- Watchers: 3
- Forks: 5
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Security: SECURITY.md
Awesome Lists containing this project
- awesome-list - guards - official | 95 | (TypeScript)
README
If you use this repo, star it ✨***
👻 Comprehensive collection of type guards for JavaScript and TypeScript
Inspired by Elixir guards
Zero dependencies 💪***
## Install
### Node.js and the browser
```sh
npm install @sniptt/guards
```### Deno
```typescript
import { ... } from 'https://deno.land/x/guards/mod.ts'// TODO
```## Usage
### Foreword on JavaScript data types and data structures
The latest ECMAScript standard defines nine types:
* Six **Data Types** that are primitives, checked by `typeof` operator:
* `undefined`: `typeof instance === "undefined"`
* `Boolean`: `typeof instance === "boolean"`
* `Number`: `typeof instance === "number"`
* `String`: `typeof instance === "string"`
* `BigInt`: `typeof instance === "bigint"`
* `Symbol`: `typeof instance === "symbol"`
* **Structural Types**:
* `Object`: `typeof instance === "object"`. Special non-data but structural type for any constructed object instance also used as data structures: new `Object`, new `Array`, new `Map`, new `Set`, new `WeakMap`, new `WeakSet`, new `Date` and almost everything made with `new` keyword;
* `Function` non data structure, though it also answers for `typeof` operator: `typeof instance === "function"`. This answer is done as a special shorthand for `Function`s, though every `Function` constructor is derived from `Object` constructor.
* **Structural Root** Primitive
* `null`: `typeof instance === "object"`. Special primitive type having additional usage for it's value: if object is not inherited, then `null` is shown;Source:
### Type coercion
![Type coercion example](.github/assets/type-coercion.png)
### Primitives
Sample usage:
```typescript
import { primitives } from '@sniptt/guards';primitives.isNumber(val);
```or
```typescript
import { isNumber } from '@sniptt/guards';isNumber(val);
```#### `isBigInt`
```typescript
import { isBigInt } from '@sniptt/guards';let val: bigint | number;
if (isBigInt(val)) {
// TypeScript will infer val: bigint
} else {
// TypeScript will infer val: number
}
```#### `isBoolean`
```typescript
import { isBoolean } from '@sniptt/guards';let val: boolean | number;
if (isBoolean(val)) {
// TypeScript will infer val: boolean
} else {
// TypeScript will infer val: number
}
```#### `isNumber`
Answers `false` to `NaN`!
See also:
* [isNumberOrNaN](#isnumberornan)
* [isInteger](#isinteger)
* [isBigInt](#isbigint)```typescript
import { isNumber } from '@sniptt/guards';let val: number | string;
if (isNumber(val)) {
// TypeScript will infer val: number
} else {
// TypeScript will infer val: string
}
```#### `isString`
```typescript
import { isString } from '@sniptt/guards';let val: string | number;
if (isString(val)) {
// TypeScript will infer val: string
} else {
// TypeScript will infer val: number
}
```#### `isSymbol`
```typescript
import { isSymbol } from '@sniptt/guards';let val: symbol | string;
if (isSymbol(val)) {
// TypeScript will infer val: symbol
} else {
// TypeScript will infer val: string
}
```#### `isUndefined`
```typescript
import { isUndefined } from '@sniptt/guards';let val: undefined | null;
if (isUndefined(val)) {
// TypeScript will infer val: undefined
} else {
// TypeScript will infer val: null
}
```### Structural
Sample usage:
```typescript
import { structural } from '@sniptt/guards';structural.isMap(val);
```or
```typescript
import { isMap } from '@sniptt/guards';isMap(val);
```#### `isNull`
Answers `true` if and only if `value === null`.
#### `isFunction`
Answers `true` if and only if `typeof value === "function"`.
#### `isObject`
Answers `false` to `null`!
To check for array:
```typescript
isArray(term)
```To check for object *or* null:
```typescript
isObjectOrNull(term)
```#### `isArray`
Answers `true` if and only if `Array.isArray(value) === true`.
#### `isMap`
Answers `true` if and only if `(value instanceof Map) === true`.
#### `isSet`
Answers `true` if and only if `(value instanceof Set) === true`.
#### `isWeakMap`
Answers `true` if and only if `(value instanceof WeakMap) === true`.
#### `isWeakSet`
Answers `true` if and only if `(value instanceof WeakSet) === true`.
#### `isDate`
Answers `true` if and only if `(value instanceof Date) === true`.
### Convenience
Sample usage:
```typescript
import { convenience } from '@sniptt/guards';convenience.isNonEmptyArray(val);
```or
```typescript
import { isNonEmptyArray } from '@sniptt/guards';isNonEmptyArray(val);
```#### `isObjectOrNull`
```typescript
test("isObjectOrNull", (t) => {
t.is(convenience.isObjectOrNull({}), true);
t.is(convenience.isObjectOrNull(null), true);
t.is(convenience.isObjectOrNull(new Set()), true);
});
```#### `isNonEmptyArray`
```typescript
test("isNonEmptyArray", (t) => {
t.is(convenience.isNonEmptyArray([1, 2]), true);
t.is(convenience.isNonEmptyArray([1]), true);
t.is(convenience.isNonEmptyArray([]), false);
});
```#### `isNonEmptyString`
```typescript
test("isNonEmptyString", (t) => {
t.is(convenience.isNonEmptyString("a"), true);
t.is(convenience.isNonEmptyString(""), false);
});
```#### `isNumberOrNaN`
```typescript
test("isNumberOrNaN", (t) => {
t.is(convenience.isNumberOrNaN(0), true);
t.is(convenience.isNumberOrNaN(42), true);
t.is(convenience.isNumberOrNaN(-42), true);
t.is(convenience.isNumberOrNaN(3.14), true);
t.is(convenience.isNumberOrNaN(-3.14), true);
t.is(convenience.isNumberOrNaN(Infinity), true);
t.is(convenience.isNumberOrNaN(-Infinity), true);
t.is(convenience.isNumberOrNaN(Number.MAX_SAFE_INTEGER), true);
t.is(convenience.isNumberOrNaN(-Number.MAX_SAFE_INTEGER), true);
t.is(convenience.isNumberOrNaN(NaN), true);
t.is(convenience.isNumberOrNaN(BigInt(0)), false);
});
```#### `isInteger`
```typescript
test("isInteger", (t) => {
t.is(convenience.isInteger(0), true);
t.is(convenience.isInteger(42), true);
t.is(convenience.isInteger(-42), true);
t.is(convenience.isInteger(3.14), false);
t.is(convenience.isInteger(-3.14), false);
t.is(convenience.isInteger(Infinity), false);
t.is(convenience.isInteger(-Infinity), false);
t.is(convenience.isInteger(Number.MAX_SAFE_INTEGER), true);
t.is(convenience.isInteger(-Number.MAX_SAFE_INTEGER), true);
t.is(convenience.isInteger(NaN), false);
});
```#### `isPositiveInteger`
```typescript
test("isPositiveInteger", (t) => {
t.is(convenience.isPositiveInteger(0), false);
t.is(convenience.isPositiveInteger(42), true);
t.is(convenience.isPositiveInteger(-42), false);
t.is(convenience.isPositiveInteger(3.14), false);
t.is(convenience.isPositiveInteger(-3.14), false);
t.is(convenience.isPositiveInteger(Infinity), false);
t.is(convenience.isPositiveInteger(-Infinity), false);
t.is(convenience.isPositiveInteger(Number.MAX_SAFE_INTEGER), true);
t.is(convenience.isPositiveInteger(-Number.MAX_SAFE_INTEGER), false);
t.is(convenience.isPositiveInteger(NaN), false);
});
```#### `isNonNegativeInteger`
```typescript
test("isNonNegativeInteger", (t) => {
t.is(convenience.isNonNegativeInteger(0), true);
t.is(convenience.isNonNegativeInteger(42), true);
t.is(convenience.isNonNegativeInteger(-42), false);
t.is(convenience.isNonNegativeInteger(3.14), false);
t.is(convenience.isNonNegativeInteger(-3.14), false);
t.is(convenience.isNonNegativeInteger(Infinity), false);
t.is(convenience.isNonNegativeInteger(-Infinity), false);
t.is(convenience.isNonNegativeInteger(Number.MAX_SAFE_INTEGER), true);
t.is(convenience.isNonNegativeInteger(-Number.MAX_SAFE_INTEGER), false);
t.is(convenience.isNonNegativeInteger(NaN), false);
});
```#### `isNegativeInteger`
```typescript
test("isNegativeInteger", (t) => {
t.is(convenience.isNegativeInteger(0), false);
t.is(convenience.isNegativeInteger(42), false);
t.is(convenience.isNegativeInteger(-42), true);
t.is(convenience.isNegativeInteger(3.14), false);
t.is(convenience.isNegativeInteger(-3.14), false);
t.is(convenience.isNegativeInteger(Infinity), false);
t.is(convenience.isNegativeInteger(-Infinity), false);
t.is(convenience.isNegativeInteger(Number.MAX_SAFE_INTEGER), false);
t.is(convenience.isNegativeInteger(-Number.MAX_SAFE_INTEGER), true);
t.is(convenience.isNegativeInteger(NaN), false);
});
```## API Docs
[Full API Documentation](docs/README.md).
## License
See [LICENSE](LICENSE)