Type check values with comprehensive TypeScript type guards and runtime assertions
—
Error-throwing assertion methods corresponding to all type checking functions, with optional custom error messages. Assertions provide runtime type validation that throws TypeError when checks fail.
The assert object contains assertion methods for all type checking functions.
/**
* Assertion methods that throw TypeError if type check fails
*/
const assert: Assert;
interface Assert {
// Basic type assertions
undefined: (value: unknown, message?: string) => asserts value is undefined;
string: (value: unknown, message?: string) => asserts value is string;
number: (value: unknown, message?: string) => asserts value is number;
boolean: (value: unknown, message?: string) => asserts value is boolean;
symbol: (value: unknown, message?: string) => asserts value is symbol;
bigint: (value: unknown, message?: string) => asserts value is bigint;
null: (value: unknown, message?: string) => asserts value is null;
// Object type assertions
array: <T = unknown>(value: unknown, assertion?: (element: unknown) => asserts element is T, message?: string) => asserts value is T[];
object: (value: unknown, message?: string) => asserts value is object;
function: (value: unknown, message?: string) => asserts value is Function;
date: (value: unknown, message?: string) => asserts value is Date;
regExp: (value: unknown, message?: string) => asserts value is RegExp;
// Multi-value assertions
all: (predicate: Predicate, ...values: unknown[]) => void | never;
any: (predicate: Predicate | Predicate[], ...values: unknown[]) => void | never;
}
type Predicate = (value: unknown) => boolean;Assert primitive and basic types with automatic error throwing.
Usage Examples:
import { assert } from '@sindresorhus/is';
// Basic assertions
assert.string('hello'); // passes
assert.string(42); // throws TypeError
assert.number(42); // passes
assert.number('42'); // throws TypeError
// Custom error messages
assert.string(someValue, 'User name must be a string');
assert.number(config.port, 'Port must be a number');
// Type narrowing
function processUserInput(name: unknown, age: unknown) {
assert.string(name); // name is now typed as string
assert.number(age); // age is now typed as number
return {
name: name.toUpperCase(),
age: age + 1
};
}Assert arrays with optional item validation.
/**
* Assert value is array, optionally validating all items
* @param value - Value to assert
* @param assertion - Optional assertion for each array item
* @param message - Optional custom error message
*/
function assertArray<T = unknown>(
value: unknown,
assertion?: (element: unknown, message?: string) => asserts element is T,
message?: string
): asserts value is T[];Usage Examples:
import { assert } from '@sindresorhus/is';
// Basic array assertion
assert.array([1, 2, 3]); // passes
assert.array('not array'); // throws TypeError
// Array with item validation
assert.array([1, 2, 3], assert.number); // passes
assert.array([1, '2', 3], assert.number); // throws (string item)
// Type narrowing with validation
function processNumbers(data: unknown) {
assert.array(data, assert.number, 'Data must be array of numbers');
// data is now typed as number[]
return data.map(n => n * 2);
}
// Custom validation
function assertStringArray(value: unknown): asserts value is string[] {
assert.array(value, assert.string, 'Must be array of strings');
}Assert conditions across multiple values.
/**
* Assert all values pass predicate
* @param predicate - Function to test each value
* @param values - Values to test
* @throws TypeError if any value fails
*/
function assertAll(predicate: Predicate, ...values: unknown[]): void | never;
/**
* Assert any value passes any predicate
* @param predicate - Single predicate or array of predicates
* @param values - Values to test
* @throws TypeError if no value passes any predicate
*/
function assertAny(predicate: Predicate | Predicate[], ...values: unknown[]): void | never;Usage Examples:
import { assert } from '@sindresorhus/is';
import is from '@sindresorhus/is';
// Assert all values match predicate
assert.all(is.string, 'hello', 'world'); // passes
assert.all(is.string, 'hello', 42); // throws
// Assert any value matches predicate
assert.any(is.string, 42, true, 'hello'); // passes (string found)
assert.any(is.string, 42, true, null); // throws (no strings)
// Multiple predicates
assert.any([is.string, is.number], 'hello', {}, []); // passes (string found)
// Function validation
function processUserData(name: unknown, email: unknown, phone: unknown) {
assert.all(is.string, name, email, phone);
// All are now typed as string
return {
name: name.trim(),
email: email.toLowerCase(),
phone: phone.replace(/\D/g, '')
};
}
function requireSomeContact(email: unknown, phone: unknown, address: unknown) {
assert.any(is.string, email, phone, address);
// At least one contact method is provided
}import { assert } from '@sindresorhus/is';
import is from '@sindresorhus/is';
interface User {
id: number;
name: string;
email: string;
age: number;
isActive: boolean;
}
function createUser(data: unknown): User {
assert.object(data, 'User data must be an object');
const userData = data as Record<string, unknown>;
assert.number(userData.id, 'User ID must be a number');
assert.string(userData.name, 'Name must be a string');
assert.string(userData.email, 'Email must be a string');
assert.number(userData.age, 'Age must be a number');
assert.boolean(userData.isActive, 'isActive must be a boolean');
// Additional validation
if (!is.positiveNumber(userData.age)) {
throw new Error('Age must be positive');
}
if (!userData.email.includes('@')) {
throw new Error('Email must be valid');
}
return userData as User;
}import { assert } from '@sindresorhus/is';
import is from '@sindresorhus/is';
interface DatabaseConfig {
host: string;
port: number;
database: string;
credentials: {
username: string;
password: string;
};
ssl: boolean;
poolSize: number;
}
function validateDatabaseConfig(config: unknown): DatabaseConfig {
assert.object(config, 'Database config must be an object');
const cfg = config as Record<string, unknown>;
// Basic type assertions
assert.string(cfg.host, 'Database host must be a string');
assert.number(cfg.port, 'Database port must be a number');
assert.string(cfg.database, 'Database name must be a string');
assert.boolean(cfg.ssl, 'SSL setting must be a boolean');
assert.number(cfg.poolSize, 'Pool size must be a number');
// Nested object validation
assert.object(cfg.credentials, 'Credentials must be an object');
const creds = cfg.credentials as Record<string, unknown>;
assert.all(is.string, creds.username, creds.password);
// Range validation
if (!is.inRange(cfg.port as number, [1, 65535])) {
throw new Error('Port must be between 1 and 65535');
}
if (!is.positiveNumber(cfg.poolSize as number)) {
throw new Error('Pool size must be positive');
}
return cfg as DatabaseConfig;
}import { assert } from '@sindresorhus/is';
import is from '@sindresorhus/is';
function processApiResponse(response: unknown) {
assert.object(response, 'API response must be an object');
const data = response as Record<string, unknown>;
assert.array(data.items, 'Response must contain items array');
// Process each item
const processedItems = (data.items as unknown[]).map((item, index) => {
assert.object(item, `Item ${index} must be an object`);
const itemData = item as Record<string, unknown>;
assert.string(itemData.id, `Item ${index} must have string ID`);
assert.string(itemData.name, `Item ${index} must have string name`);
// Optional fields
if (itemData.description !== undefined) {
assert.string(itemData.description, `Item ${index} description must be string`);
}
return {
id: itemData.id,
name: itemData.name,
description: itemData.description as string | undefined
};
});
return processedItems;
}import { assert } from '@sindresorhus/is';
import is from '@sindresorhus/is';
interface ContactForm {
name: string;
email: string;
subject: string;
message: string;
subscribe: boolean;
}
function validateContactForm(formData: unknown): ContactForm {
assert.object(formData, 'Form data is required');
const data = formData as Record<string, unknown>;
// Required string fields
const requiredFields = ['name', 'email', 'subject', 'message'];
assert.all(is.string, ...requiredFields.map(field => data[field]));
// Additional validations
const form = data as Partial<ContactForm>;
if (!is.nonEmptyStringAndNotWhitespace(form.name)) {
throw new Error('Name cannot be empty');
}
if (!form.email?.includes('@')) {
throw new Error('Email must be valid');
}
if (!is.nonEmptyStringAndNotWhitespace(form.subject)) {
throw new Error('Subject is required');
}
if (!is.nonEmptyStringAndNotWhitespace(form.message)) {
throw new Error('Message is required');
}
// Optional boolean field
const subscribe = data.subscribe !== undefined ?
(assert.boolean(data.subscribe), data.subscribe) : false;
return {
name: form.name!,
email: form.email!,
subject: form.subject!,
message: form.message!,
subscribe
};
}import { assert } from '@sindresorhus/is';
// Custom assertion wrapper
function assertWithContext<T>(
value: unknown,
assertion: (value: unknown, message?: string) => asserts value is T,
context: string
): asserts value is T {
try {
assertion(value);
} catch (error) {
throw new Error(`${context}: ${error.message}`);
}
}
// Usage
function processUser(userData: unknown, userId: string) {
assertWithContext(userData, assert.object, `User ${userId}`);
const user = userData as Record<string, unknown>;
assertWithContext(user.name, assert.string, `User ${userId} name`);
assertWithContext(user.age, assert.number, `User ${userId} age`);
}
// Batch validation with detailed errors
function validateBatch<T>(
items: unknown[],
assertion: (value: unknown, message?: string) => asserts value is T,
itemName: string
): T[] {
return items.map((item, index) => {
try {
assertion(item, `${itemName} at index ${index} is invalid`);
return item;
} catch (error) {
throw new Error(`Validation failed for ${itemName}[${index}]: ${error.message}`);
}
});
}When assertions fail, they throw TypeError with descriptive messages:
// Default error format
assert.string(42);
// TypeError: Expected value which is `string`, received value of type `number`.
assert.array('not array');
// TypeError: Expected value which is `Array`, received value of type `string`.All assertion methods (except assertAll and assertAny) support custom error messages:
import { assert } from '@sindresorhus/is';
assert.string(42, 'Username must be a string');
// TypeError: Username must be a string
assert.number(config.port, 'Configuration port must be a number');
// TypeError: Configuration port must be a number
assert.array(data, assert.string, 'Expected array of strings');
// TypeError: Expected array of stringsTypeError on failure, never return valuesassertAll and assertAny do not support custom messagesInstall with Tessl CLI
npx tessl i tessl/npm-sindresorhus--is