isguard-ts
v2.2.0
Published
a typescript library for building type guards quickly and in a type safe way
Downloads
186
Maintainers
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
- isType
- isTuple
- isUnion
- isIntersection
- isArray
- isEnum
- isSet
- isMap
- isRecord
- isPartialRecord
- isIndexRecord
- isRecursive
- isInstanceof
- isValue
- isValueUnion
- isOptional
- isMaybe
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 theTypeGuard
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>;