JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 34
  • Score
    100M100P100Q77292F
  • License ISC

a typescript library for building type guards quickly and in a type safe way

Package Exports

  • isguard-ts
  • isguard-ts/dist/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (isguard-ts) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

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>(() => ({
    value: isNumber,
    left: isMaybe(isTree), // isTree is the return type of isType
    right: isMaybe(isTree),
}));

// isTree can also be accessed via the passed function's parameter
const isTree2 = isType<Tree>(isTreeParam => ({
    value: isNumber,
    left: isMaybe(isTreeParam), // isTreeParam === isTree2
    right: isMaybe(isTreeParam),
}));

For generic types you would need to create your own type guard generator

import { TypeGuard, isType } 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>(() => [
    isNumber,
    isMaybe(isRow),
]);

// isRow can also be accessed via the function's parameter
const isRow2 = isTuple<Row>(isRowParam => [
    isNumber,
    isMaybe(isRowParam), // isRowParam === isRow2
]);

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, TypeGuard, 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 { TypeGuard, 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 { TypeGuard, 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 { TypeGuard, 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 { TypeGuard, 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 { TypeGuard, isIndexRecord, isNumber } from "isguard-ts";

const isNumberRecord = isIndexRecord(isNumber);

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

Helps you create type guards for classes

import { TypeGuard, 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 { TypeGuard, 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 { TypeGuard, 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 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>;