typeguard-ts
v2.2.1
Published
Simple functions to check if a variable type is really what he supposed to be.
Maintainers
Readme
typeguard-ts
Small, composable runtime type guards for TypeScript.
Validate unknown values at runtime while keeping TypeScript type narrowing.
import {
isObjectCreate,
isString,
isPositiveInteger,
isOptional,
isArrayOfCreate,
} from 'typeguard-ts';
interface User {
id: number;
name: string;
tags?: string[];
}
const isUser = isObjectCreate<User>({
id: isPositiveInteger,
name: isString,
tags: isOptional(isArrayOfCreate(isString)),
});
const value: unknown = {
id: 1,
name: 'Alice',
tags: ['typescript', 'validation'],
};
if (isUser(value)) {
// value is User
console.log(value.name);
}Why typeguard-ts?
TypeScript types disappear at runtime.
const value: unknown = JSON.parse(data);TypeScript cannot know whether value actually matches the type you expect.
typeguard-ts lets you validate runtime values with reusable type guards:
if (isUser(value)) {
// value is User
console.log(value.name);
}The main idea behind this package is composition.
Build complex validators from small reusable type guards:
const isOptionalString = isOptional(isString);
const isStringArray = isArrayOfCreate(isString);
const isOptionalStringArray = isOptional(
isArrayOfCreate(isString),
);
const isPercentage = isNumberBetweenCreate(0, 100);Features
- TypeScript type narrowing
- Runtime validation for
unknown - Small, composable type guards
- Zero dependencies
- Primitive type guards
- Object shape validation
- Array and
Setvalidation - String and number validators
- Optional and nullable values
- Type guard combinators
- Reusable type guard factories
Installation
npm install typeguard-tsOr with pnpm:
pnpm add typeguard-tsOr with yarn:
yarn add typeguard-tsBasic Usage
All validators accept unknown values.
import { isString, isNumber } from 'typeguard-ts';
const value: unknown = getValue();
if (isString(value)) {
// value is string
console.log(value.toUpperCase());
}
if (isNumber(value)) {
// value is number
console.log(value.toFixed(2));
}API
Primitive Type Guards
isBoolean
Checks whether a value is a boolean.
isBoolean(value: unknown): value is booleanisBoolean(true); // true
isBoolean(false); // true
isBoolean(1); // falseisString
Checks whether a value is a string.
isString(value: unknown): value is stringisString('hello'); // true
isString(123); // falseisNumber
Checks whether a value is a finite number.
NaN, Infinity, and -Infinity are rejected.
isNumber(value: unknown): value is numberisNumber(10); // true
isNumber(3.14); // true
isNumber(NaN); // false
isNumber(Infinity); // false
isNumber(-Infinity); // falseisBigInt
Checks whether a value is a bigint.
isBigInt(value: unknown): value is bigintisBigInt(1n); // true
isBigInt(1); // falseisSymbol
Checks whether a value is a symbol.
isSymbol(value: unknown): value is symbolisSymbol(Symbol('id')); // true
isSymbol('id'); // falseisNull
Checks whether a value is null.
isNull(value: unknown): value is nullisNull(null); // true
isNull(undefined); // falseisUndefined
Checks whether a value is undefined.
isUndefined(value: unknown): value is undefinedisUndefined(undefined); // true
isUndefined(null); // falseisNaN
Checks whether a value is JavaScript's NaN.
isNaN(value: unknown): value is numberisNaN(NaN); // true
isNaN(10); // falseisInfinite
Checks whether a value is positive or negative infinity.
isInfinite(value: unknown): value is numberisInfinite(Infinity); // true
isInfinite(-Infinity); // true
isInfinite(10); // falseisArray
Checks whether a value is an array.
isArray(value: unknown): value is unknown[]isArray([]); // true
isArray([1, 2, 3]); // true
isArray('hello'); // falseisFunction
Checks whether a value is a function.
isFunction(value: unknown): value is FunctionisFunction(() => {}); // true
isFunction('hello'); // falseisDate
Checks whether a value is a valid Date.
Invalid Date objects are rejected.
isDate(value: unknown): value is DateisDate(new Date()); // true
isDate(new Date('invalid')); // false
isDate('2026-08-15'); // falseisSet
Checks whether a value is a Set.
isSet(value: unknown): value is Set<unknown>isSet(new Set()); // true
isSet([]); // falseisEqual
Checks whether a value is strictly equal to an expected value.
isEqual<T>(
value: unknown,
expected: T,
): value is TisEqual(10, 10); // true
isEqual('hello', 'hello'); // true
isEqual(10, '10'); // falseisInstanceOf
Checks whether a value is an instance of a constructor.
isInstanceOf<T>(
value: unknown,
type: new (...args: unknown[]) => T,
): value is Tclass User {}
const value: unknown = new User();
if (isInstanceOf(value, User)) {
// value is User
}isPlainObject
Checks whether a value is a plain object.
Arrays and null are rejected.
Objects with either Object.prototype or null as their prototype are accepted.
isPlainObject({}); // true
isPlainObject(Object.create(null)); // true
isPlainObject([]); // false
isPlainObject(null); // false
isPlainObject(new Date()); // falseFunction Validators
isArrowFunction
Checks whether a function does not have its own prototype property.
isArrowFunction(value: unknown): value is FunctionisArrowFunction(() => {}); // true
function regular() {}
isArrowFunction(regular); // falseisRegularFunction
Checks whether a function has its own prototype property.
isRegularFunction(value: unknown): value is Functionfunction regular() {}
isRegularFunction(regular); // true
isRegularFunction(() => {}); // falseThese validators classify functions based on whether they have an own
prototypeproperty.
String Validators
isStringByRegex
Checks whether a value is a string matching a regular expression.
isStringByRegex(
value: unknown,
regex: RegExp,
): value is stringisStringByRegex(
'abc123',
/^[a-z0-9]+$/,
); // true
isStringByRegex(
'hello!',
/^[a-z0-9]+$/,
); // falseisNonEmptyString
Checks whether a string contains at least one non-whitespace character.
isNonEmptyString(value: unknown): value is stringisNonEmptyString('hello'); // true
isNonEmptyString(''); // false
isNonEmptyString(' '); // falseisWhitespaceFreeString
Checks whether a string contains no whitespace characters.
isWhitespaceFreeString(value: unknown): value is stringisWhitespaceFreeString('hello'); // true
isWhitespaceFreeString('hello-world'); // true
isWhitespaceFreeString('hello world'); // falseisDateString
Checks whether a value is a string that can be parsed by Date.parse().
isDateString(value: unknown): value is stringisDateString('2026-08-15'); // true
isDateString('hello'); // false
isDateStringfollows JavaScript'sDate.parse()behavior and does not enforce a specific date format.
Number Validators
All number validators use isNumber, so NaN and infinite numbers are rejected.
isInteger
Checks whether a value is an integer.
isInteger(value: unknown): value is numberisInteger(10); // true
isInteger(10.5); // falseisPositiveNumber
Checks for numbers greater than 0.
isPositiveNumber(5); // true
isPositiveNumber(0); // false
isPositiveNumber(-5); // falseisPositiveInteger
Checks for integers greater than 0.
isPositiveInteger(5); // true
isPositiveInteger(1.5); // false
isPositiveInteger(0); // falseisNonNegativeNumber
Checks for numbers greater than or equal to 0.
isNonNegativeNumber(0); // true
isNonNegativeNumber(10); // true
isNonNegativeNumber(-1); // falseisNonNegativeInteger
Checks for integers greater than or equal to 0.
isNonNegativeInteger(0); // true
isNonNegativeInteger(10); // true
isNonNegativeInteger(-1); // falseisNegativeNumber
Checks for numbers less than 0.
isNegativeNumber(-5); // true
isNegativeNumber(0); // falseisNegativeInteger
Checks for integers less than 0.
isNegativeInteger(-5); // true
isNegativeInteger(-5.5); // falseisNonPositiveNumber
Checks for numbers less than or equal to 0.
isNonPositiveNumber(-5); // true
isNonPositiveNumber(0); // true
isNonPositiveNumber(5); // falseisNonPositiveInteger
Checks for integers less than or equal to 0.
isNonPositiveInteger(-5); // true
isNonPositiveInteger(0); // true
isNonPositiveInteger(-5.5); // falseisNumberBetween
Checks whether a number is between min and max, inclusive.
isNumberBetween(
value: unknown,
min: number,
max: number,
): value is numberisNumberBetween(5, 1, 10); // true
isNumberBetween(1, 1, 10); // true
isNumberBetween(10, 1, 10); // true
isNumberBetween(15, 1, 10); // falseSpecial Validators
isNil
Checks whether a value is null or undefined.
isNil(value: unknown): value is null | undefinedisNil(null); // true
isNil(undefined); // true
isNil(0); // falseObject Validation
isObject
Validates a plain object's keys using a shape of type guards.
isObject<T>(
value: unknown,
shape: {
[K in keyof Required<T>]:
(item: unknown) => item is T[K];
},
): value is Tinterface User {
id: number;
name: string;
}
const value: unknown = {
id: 123,
name: 'John',
};
const isUser = isObjectCreate<User>({
id: isPositiveInteger,
name: isNonEmptyString,
});
if (isUser(value)) {
// value is User
console.log(value.name);
}isObject validates every key defined in the shape.
It also rejects keys on the value that are not defined in the shape.
Optional properties
Use isOptional for optional properties.
interface User {
id: number;
nickname?: string;
}
const isUser = isObjectCreate<User>({
id: isPositiveInteger,
nickname: isOptional(isString),
});isUser({
id: 1,
}); // true
isUser({
id: 1,
nickname: 'Alice',
}); // trueArray Validators
isArrayOf
Checks whether a value is an array where every item passes the supplied type guard.
isArrayOf<T>(
value: unknown,
isItem: (item: unknown) => item is T,
): value is T[]isArrayOf(
['a', 'b', 'c'],
isString,
); // true
isArrayOf(
['a', 1, 'c'],
isString,
); // falseisNonEmptyArrayOf
Checks whether a value is a non-empty array.
An item validator is optional.
isNonEmptyArrayOf<T>(
value: unknown,
isItem?: (item: unknown) => item is T,
): value is T[]isNonEmptyArrayOf(['a', 'b']); // true
isNonEmptyArrayOf([]); // falseWith item validation:
isNonEmptyArrayOf(
['a', 'b'],
isString,
); // true
isNonEmptyArrayOf(
['a', 1],
isString,
); // falseisArrayInLengthOf
Checks an array's length.
The length can be an exact number or another type guard.
An item validator is optional.
isArrayInLengthOf<T>(
value: unknown,
isValidLength:
| number
| ((length: unknown) => length is number),
isItem?: (item: unknown) => item is T,
): value is T[]Exact length:
isArrayInLengthOf(
['a', 'b'],
2,
); // trueLength validator:
isArrayInLengthOf(
['a', 'b'],
isPositiveInteger,
); // trueLength and item validation:
isArrayInLengthOf(
['a', 'b'],
isPositiveInteger,
isString,
); // trueSet Validators
isSetOf
Checks whether a value is a Set where every item passes the supplied type guard.
isSetOf<T>(
value: unknown,
isItem: (item: unknown) => item is T,
): value is Set<T>isSetOf(
new Set(['a', 'b']),
isString,
); // true
isSetOf(
new Set(['a', 123]),
isString,
); // falseisSetInLengthOf
Checks a Set's size.
The size can be an exact number or another type guard.
An item validator is optional.
isSetInLengthOf<T>(
value: unknown,
isValidLength:
| number
| ((length: unknown) => length is number),
isItem?: (item: unknown) => item is T,
): value is Set<T>isSetInLengthOf(
new Set(['a', 'b']),
2,
); // trueisSetInLengthOf(
new Set(['a', 'b']),
isPositiveInteger,
isString,
); // trueType Guard Combinators
isOneOfTypes
Returns true when at least one supplied type guard accepts the value.
isOneOfTypes<T>(
value: unknown,
isTypes: ((item: unknown) => item is T)[],
): value is TisOneOfTypes(value, [
isString,
isNumber,
]);isAllOfTypes
Returns true when every supplied type guard accepts the value.
isAllOfTypes<T>(
value: unknown,
isTypes: ((item: unknown) => item is T)[],
): value is TisAllOfTypes(value, [
isInteger,
isPositiveNumber,
]);isOnlyOneOfTypes
Deprecated
Returns true only when exactly one supplied type guard accepts the value.
isOnlyOneOfTypes<T>(
value: unknown,
isTypes: ((item: unknown) => item is T)[],
): value is TisOnlyOneOfTypes(value, [
isString,
isNumber,
]);This function is mainly useful when custom type guards overlap unexpectedly.
Type Guard Factories
Factories create reusable type guards from existing validators.
isOptional
Makes a type guard also accept undefined.
const isOptionalString = isOptional(isString);
isOptionalString('hello'); // true
isOptionalString(undefined); // true
isOptionalString(123); // falseisNullable
Makes a type guard also accept null.
const isNullableString = isNullable(isString);
isNullableString('hello'); // true
isNullableString(null); // true
isNullableString(123); // falseisOneOfTypesCreate
Creates a reusable guard that passes when at least one supplied guard passes.
const isStringOrNumber = isOneOfTypesCreate([
isString,
isNumber,
]);
isStringOrNumber('hello'); // true
isStringOrNumber(123); // true
isStringOrNumber(true); // falseisAllOfTypesCreate
Creates a reusable guard that requires every supplied guard to pass.
const isPositiveIntegerGuard = isAllOfTypesCreate([
isInteger,
isPositiveNumber,
]);
isPositiveIntegerGuard(10); // true
isPositiveIntegerGuard(-10); // false
isPositiveIntegerGuard(1.5); // falseisOnlyOneOfTypesCreate
Deprecated
Creates a reusable guard that requires exactly one supplied guard to pass.
const isExactlyOne = isOnlyOneOfTypesCreate([
isString,
isNumber,
]);isArrayOfCreate
Creates a reusable array validator.
const isStringArray = isArrayOfCreate(isString);
isStringArray(['a', 'b']); // true
isStringArray(['a', 1]); // falseisSetOfCreate
Creates a reusable Set validator.
const isStringSet = isSetOfCreate(isString);
isStringSet(
new Set(['a', 'b']),
); // trueisArrayInLengthOfCreate
Creates a reusable array length validator.
const isNonEmptyStringArray = isArrayInLengthOfCreate(
isPositiveInteger,
isString,
);
isNonEmptyStringArray(['a', 'b']); // true
isNonEmptyStringArray([]); // falseAn item validator is optional:
const isNonEmptyArray = isArrayInLengthOfCreate(
isPositiveInteger,
);isSetInLengthOfCreate
Creates a reusable Set size validator.
const isNonEmptyStringSet = isSetInLengthOfCreate(
isPositiveInteger,
isString,
);An item validator is optional:
const isNonEmptySet = isSetInLengthOfCreate(
isPositiveInteger,
);isObjectCreate
Creates a reusable object type guard from a shape.
interface User {
id: number;
name: string;
}
const isUser = isObjectCreate<User>({
id: isPositiveInteger,
name: isNonEmptyString,
});
const value: unknown = {
id: 123,
name: 'John',
};
if (isUser(value)) {
// value is User
console.log(value.name);
}isNumberBetweenCreate
Creates a reusable number range validator.
const isPercentage = isNumberBetweenCreate(
0,
100,
);
isPercentage(50); // true
isPercentage(100); // true
isPercentage(101); // false
isPercentage(-1); // falseisStringByRegexCreate
Creates a reusable regex validator.
const isUsername = isStringByRegexCreate(
/^[a-zA-Z0-9_]+$/,
);
isUsername('john_123'); // true
isUsername('john doe'); // falseisEqualCreate
Creates a reusable strict equality validator.
const isSuccess = isEqualCreate('success');
isSuccess('success'); // true
isSuccess('error'); // falseisInstanceOfCreate
Creates a reusable class instance validator.
class User {
constructor(
public name: string,
) {}
}
const isUser = isInstanceOfCreate(User);
const value: unknown = new User('John');
if (isUser(value)) {
console.log(value.name);
}Composition
The main purpose of typeguard-ts is to build complex validators from simple ones.
Instead of creating separate validators for every combination:
isOptionalString()
isStringArray()
isOptionalStringArray()
isPositiveIntegerArray()Compose existing guards:
const isOptionalString = isOptional(
isString,
);
const isStringArray = isArrayOfCreate(
isString,
);
const isOptionalStringArray = isOptional(
isArrayOfCreate(isString),
);
const isPercentage = isNumberBetweenCreate(
0,
100,
);You can also compose your own custom guards:
const isStartsWithA = (
value: unknown,
): value is string => {
return (
isString(value) &&
value.startsWith('A')
);
};
const isNameArray = isArrayOfCreate(
isStartsWithA,
);Common Use Cases
typeguard-ts is useful for validating:
- API request bodies
- API responses
JSON.parse()results- External data
- Environment variables
- Database results
- User input
- Any
unknownvalue
Design Philosophy
typeguard-ts focuses on small, reusable, composable type guards.
Instead of adding a new function for every possible combination, existing guards can be combined to create the validator you need.
const isOptionalStringArray = isOptional(
isArrayOfCreate(isString),
);const isPercentageArray = isArrayOfCreate(
isNumberBetweenCreate(0, 100),
);Build small guards once. Compose them wherever you need them.
License
MIT
