isguard-ts
TypeScript icon, indicating that this package has built-in type declarations

2.2.0 • Public • Published

isguard-ts

A powerful typescript library that helps you build type guards.
isguard-ts utilizes the typescript compiler to ensure the type guards are type safe and fast to create.

Some of our built-in types

Some of our built-in helper functions

Some of our utility type guards

  • isString, isNumber, isBoolean, isDate
  • isStringArray, isNumberArray, isBooleanArray, isDateArray
  • isNull, isUndefined, isNil
  • isUnknown - always returns true
  • isNever - always returns false
  • and more

Types

TypeGuard<T>

The most basic type - represents a type guard of T

type TypeGuard<T> = (value: unknown) => value is T;

Guarded<T>

Extracts T out of TypeGuard<T>

import { Guarded, TypeGuard } from "isguard-ts";

type Extracted = Guarded<TypeGuard<number>>; // number

Code Examples

Note that these code examples may contain Best Practice sections
You are advised to follow them closely when you write your code

isType<T>(template): TypeGuard<T>

Helps you create type guards for types and interfaces

Best Practice: Pass the generic type argument into isType
Otherwise optional fields might have an unexpected behavior

import { isType, isString, isNumber } from "isguard-ts";

type Person = {
	name: string;
	age: number;
};

const isPerson = isType<Person>({
	name: isString,
	age: isNumber,
});

isPerson({ name: "Hello", age: 6 }); // true

isType also supports recursive types by passing a function as an argument

import { isType, isNumber, isMaybe } from "isguard-ts";

type Tree = {
	value: number;
	left: Tree | null;
	right: Tree | null;
};

const isTree = isType<Tree>(isTreeParam => ({
	value: isNumber,
	left: isMaybe(isTreeParam), // isTreeParam === isTree
	right: isMaybe(isTreeParam),
}));

For generic types you would need to create your own TypeGuard generator

import { TypeGuard, isType, isNumber } from "isguard-ts";

type ValueHolder<T> = {
	value: T;
};

const isValueHolder = <T>(isValue: TypeGuard<T>): TypeGuard<ValueHolder<T>> => {
	return isType<ValueHolder<T>>({
		value: isValue,
	});
};

const isNumberHolder: TypeGuard<ValueHolder<number>> = isValueHolder(isNumber);

isTuple<T>(template): TypeGuard<T>

Helps you create type guards for tuples

Best Practice: Pass the generic type argument into isTuple
Otherwise optional fields might have an unexpected behavior

import { isTuple, isNumber, isOptionalString } from "isguard-ts";

type Row = [number, string?];

const isRow = isTuple<Row>([isNumber, isOptionalString]);

isRow([6, "Hello"]); // true
isRow([6]); // true
isRow(["Hello", "Bye"]); // false

Just like isType, isTuple supports recursive tuples

import { isTuple, isNumber, isMaybe } from "isguard-ts";

type Row = [number, Row | null];

const isRow = isTuple<Row>(isRowParam => [
	isNumber,
	isMaybe(isRowParam), // isRowParam === isRow
]);

isUnion<[T1, T2, ...]>(...guards): TypeGuard<T1 | T2 | ...>

Helps you create type guards for unions

Best Practice: Add a type annotation to the result of isUnion
This ensures the result is of the expected type

import { isType, isNumber, isString, TypeGuard, isUnion } from "isguard-ts";

type A = { a: number };
type B = { b: string };
type C = A | B;

const isA = isType<A>({ a: isNumber });
const isB = isType<B>({ b: isString });

const isC: TypeGuard<C> = isUnion(isA, isB);

isC({ a: 6 }); // true
isC({ b: "Hello" }); // true
isC({ a: new Date() }); // false

isIntersection<[T1, T2, ...]>(...guards): TypeGuard<T1 & T2 & ...>

Helps you create type guards for intersections

Best Practice: Add a type annotation to the result of isIntersection
This ensures the result is of the expected type

import { isType, isNumber, isString, TypeGuard, isIntersection } from "isguard-ts";

type A = { a: number };
type B = { b: string };
type C = A & B;

const isA = isType<A>({ a: isNumber });
const isB = isType<B>({ b: isString });

const isC: TypeGuard<C> = isIntersection(isA, isB);

isArray<T>(guard: TypeGuard<T>): TypeGuard<T[]>

Helps you create type guards for arrays

import { isType, isNumber, isArray } from "isguard-ts";

type Test = {
	a: number;
};

const isTest = isType<Test>({ a: isNumber });
const isTestArray = isArray(isTest);

isEnum<T>(enumObj: T): TypeGuard<T[keyof T]>

Helps you create type guards for enums

import { isEnum } from "isguard-ts";

enum Direction {
	up = 0,
	down = 1,
	left = 2,
	right = 3,
}

const isDirection = isEnum(Direction);

isDirection(Direction.up); // true
isDirection(2); // true
isDirection("hello"); // false

isSet<T>(guard: TypeGuard<T>): TypeGuard<Set<T>>

Helps you create type guards for sets

import { isSet, isNumber } from "isguard-ts";

const isNumberSet = isSet(isNumber);

isMap<K, V>(isKey: TypeGuard<K>, isValue: TypeGuard<V>): TypeGuard<Map<K, V>>

Helps you create type guards for maps

import { isMap, isString, isBoolean } from "isguard-ts";

const isStringBooleanMap = isMap(isString, isBoolean);

isRecord<K, V>(keys: K, isValue: TypeGuard<V>): TypeGuard<Record<K[number], V>>

Helps you create type guards for records

import { isRecord, isNumber } from "isguard-ts";

const timeUnits = ["second", "minute", "hour"] as const;
type TimeUnit = (typeof timeUnits)[number];

type TimeUnitToMillisecond = Record<TimeUnit, number>;
const isTimeUnitToMillisecond = isRecord(timeUnits, isNumber);

isPartialRecord<K, V>(keys: K, isValue: TypeGuard<V>): TypeGuard<Partial<Record<K[number], V>>>

Works just like isRecord but allows for undefined values

import { isPartialRecord, isNumber } from "isguard-ts";

const timeUnits = ["second", "minute", "hour"] as const;
type TimeUnit = (typeof timeUnits)[number];

type PartialTimeUnitToMillisecond = Partial<Record<TimeUnit, number>>;
const isPartialTimeUnitToMillisecond = isPartialRecord(timeUnits, isNumber);

isIndexRecord<V>(isValue: TypeGuard<V>): TypeGuard<Record<PropertyKey, V>>

Works just like isRecord but checks only the values and not the keys

import { isIndexRecord, isNumber } from "isguard-ts";

const isNumberRecord = isIndexRecord(isNumber);

isRecursive<T>(generator): TypeGuard<T>

Helps you create type guards for recursive types

Best Practice: Pass the generic type argument into isRecursive
To ensure the TypeGuard returned is of the desired type

import { isRecursive, isType, isNumber, isOptional } from "isguard-ts";

type Node = {
	value: number;
	next?: Node;
};

const isNode = isRecursive<Node>(isNodeParam => isType<Node>({
	value: isNumber,
	next: isOptional(isNodeParam), // isNodeParam === isNode
}));
import { isRecursive, isTuple, isNumber, isOptional } from "isguard-ts";

type Row = [number, Row?];

const isRow = isRecursive<Row>(isRowParam => isTuple<Row>([
	isNumber,
	isOptional(isRowParam), // isRowParam === isRow
]));
import { isRecursive, isUnion, isNumber, isString, isBoolean, isNull, isArray, isIndexRecord } from "isguard-ts";

type Json =
	number |
	string |
	boolean |
	null |
	Json[] |
	{ [key: string]: Json; };

const isJson = isRecursive<Json>(isJsonParam => isUnion(
	isNumber,
	isString,
	isBoolean,
	isNull,
	isArray(isJsonParam), // isJsonParam === isJson
	isIndexRecord(isJsonParam),
));

isInstanceof<T>(constructor): TypeGuard<T>

Helps you create type guards for classes

import { isInstanceof } from "isguard-ts";

abstract class Animal { }
class Dog extends Animal { }

const isAnimal = isInstanceof(Animal);
const isDog = isInstanceof(Dog);

isValue<T>(value: T): TypeGuard<T>

Helps you create type guards for value literals

import { isValue } from "isguard-ts";

const isHello = isValue("Hello");
const is12 = isValue(12);

isValueUnion<[T1, T2, ...]>(values): TypeGuard<T1 | T2 | ...>

Helps you create type guards for union of value literals

import { isValueUnion } from "isguard-ts";

const isHelloOrBye = isValueUnion("Hello", "Bye");

isOptional<T>(guard: TypeGuard<T>): TypeGuard<T | undefined>

Helps you create type guards for optional types

import { isOptional, isNumber } from "isguard-ts";

const isNumberOrUndefined = isOptional(isNumber);

isMaybe<T>(guard: TypeGuard<T>): TypeGuard<T | null>

Helps you create type guards for nullable types

import { isMaybe, isNumber } from "isguard-ts";

const isNumberOrNul = isMaybe(isNumber);

All utility type guards

const isNumber: TypeGuard<number>;
const isBigint: TypeGuard<bigint>;
const isString: TypeGuard<string>;
const isBoolean: TypeGuard<boolean>;
const isSymbol: TypeGuard<symbol>;
const isFunction: TypeGuard<Function>;
const isPropertyKey: TypeGuard<PropertyKey>;

const isDate: TypeGuard<Date>;
const isRegExp: TypeGuard<RegExp>;
const isObject: TypeGuard<object>;
const isError: TypeGuard<Error>;
const isEvalError: TypeGuard<EvalError>;
const isRangeError: TypeGuard<RangeError>;
const isReferenceError: TypeGuard<ReferenceError>;
const isSyntaxError: TypeGuard<SyntaxError>;
const isTypeError: TypeGuard<TypeError>;
const isURIError: TypeGuard<URIError>;

const isNull: TypeGuard<null>;
const isUndefined: TypeGuard<undefined>;
const isNil: TypeGuard<null | undefined>;

const isNumberArray: TypeGuard<number[]>;
const isStringArray: TypeGuard<string[]>;
const isBooleanArray: TypeGuard<boolean[]>;
const isDateArray: TypeGuard<Date[]>;

const isOptionalNumber: TypeGuard<number | undefined>;
const isOptionalString: TypeGuard<string | undefined>;
const isOptionalBoolean: TypeGuard<boolean | undefined>;
const isOptionalDate: TypeGuard<Date | undefined>;

const isMaybeNumber: TypeGuard<number | null>;
const isMaybeString: TypeGuard<string | null>;
const isMaybeBoolean: TypeGuard<boolean | null>;
const isMaybeDate: TypeGuard<Date | null>;

const isTrue: TypeGuard<true>;
const isFalse: TypeGuard<false>;

const isUnknown: TypeGuard<unknown>;
const isNever: TypeGuard<never>;

Package Sidebar

Install

npm i isguard-ts

Weekly Downloads

84

Version

2.2.0

License

ISC

Unpacked Size

32.5 kB

Total Files

38

Last publish

Collaborators

  • razhy04