Type check values with comprehensive TypeScript type guards and runtime assertions
—
Specialized number validation including integers, safe integers, positive/negative numbers, even/odd checks, range validation, and mathematical properties.
Check if a value is an integer or safe integer.
/**
* Check if value is an integer
* @param value - Value to check
* @returns True if value is integer
*/
function isInteger(value: unknown): value is number;
/**
* Check if value is a safe integer (within safe integer range)
* @param value - Value to check
* @returns True if value is safe integer
*/
function isSafeInteger(value: unknown): value is number;Usage Examples:
import is from '@sindresorhus/is';
is.integer(42); // => true
is.integer(3.14); // => false
is.integer(Number.MAX_VALUE); // => false (too large to be precise)
is.safeInteger(42); // => true
is.safeInteger(Number.MAX_SAFE_INTEGER); // => true
is.safeInteger(Number.MAX_SAFE_INTEGER + 1); // => false
is.safeInteger(3.14); // => false
// Type guard usage
function processArrayIndex(index: unknown) {
if (is.safeInteger(index) && index >= 0) {
// index is now typed as number and guaranteed to be safe
return `Item at index ${index}`;
}
throw new Error('Invalid array index');
}Check if numbers are positive or negative.
/**
* Check if value is a positive number
* @param value - Value to check
* @returns True if value is positive number
*/
function isPositiveNumber(value: unknown): value is number;
/**
* Check if value is a negative number
* @param value - Value to check
* @returns True if value is negative number
*/
function isNegativeNumber(value: unknown): value is number;Usage Examples:
import is from '@sindresorhus/is';
is.positiveNumber(42); // => true
is.positiveNumber(0); // => false
is.positiveNumber(-5); // => false
is.positiveNumber('42'); // => false
is.negativeNumber(-42); // => true
is.negativeNumber(0); // => false
is.negativeNumber(5); // => false
// Type guard usage
function calculateDiscount(amount: unknown, discount: unknown) {
if (is.positiveNumber(amount) && is.positiveNumber(discount)) {
// Both are now typed as positive numbers
return amount - (amount * discount / 100);
}
throw new Error('Amount and discount must be positive numbers');
}Check if integers are even or odd.
/**
* Check if value is an even integer
* @param value - Value to check
* @returns True if value is even integer
*/
function isEvenInteger(value: unknown): value is number;
/**
* Check if value is an odd integer
* @param value - Value to check
* @returns True if value is odd integer
*/
function isOddInteger(value: unknown): value is number;Usage Examples:
import is from '@sindresorhus/is';
is.evenInteger(2); // => true
is.evenInteger(3); // => false
is.evenInteger(0); // => true
is.evenInteger(2.5); // => false
is.oddInteger(3); // => true
is.oddInteger(2); // => false
is.oddInteger(1.5); // => false
// Type guard usage
function processNumbers(numbers: unknown[]) {
const evens = numbers.filter(is.evenInteger);
const odds = numbers.filter(is.oddInteger);
console.log('Even numbers:', evens);
console.log('Odd numbers:', odds);
}Check if a value is positive or negative infinity.
/**
* Check if value is Infinity or -Infinity
* @param value - Value to check
* @returns True if value is infinite
*/
function isInfinite(value: unknown): value is number;Usage Examples:
import is from '@sindresorhus/is';
is.infinite(Infinity); // => true
is.infinite(-Infinity); // => true
is.infinite(Number.POSITIVE_INFINITY); // => true
is.infinite(Number.NEGATIVE_INFINITY); // => true
is.infinite(42); // => false
is.infinite(NaN); // => false
// Type guard usage
function safeDivision(a: number, b: number) {
const result = a / b;
if (is.infinite(result)) {
throw new Error('Division resulted in infinity');
}
return result;
}Check if a number is within a specified range.
/**
* Check if number is within specified range
* @param value - Number to check
* @param range - Range as single number (0 to range) or [min, max] tuple
* @returns True if value is in range
*/
function isInRange(value: number, range: number | [number, number]): value is number;Usage Examples:
import is from '@sindresorhus/is';
// Single number range (0 to range)
is.inRange(5, 10); // => true (0 <= 5 <= 10)
is.inRange(-2, 10); // => false (negative values not allowed)
is.inRange(15, 10); // => false (above range)
// Array range [min, max]
is.inRange(5, [0, 10]); // => true
is.inRange(5, [10, 20]); // => false
is.inRange(15, [10, 20]); // => true
// Range order doesn't matter
is.inRange(5, [10, 0]); // => true (same as [0, 10])
// Type guard usage (value is already number)
function processScore(score: number) {
if (is.inRange(score, [0, 100])) {
// score is guaranteed to be 0-100
const grade = score >= 90 ? 'A' : score >= 80 ? 'B' : 'C';
return grade;
}
throw new Error('Score must be between 0 and 100');
}
// Validation with unknown input
function validateAge(age: unknown) {
if (is.number(age) && is.inRange(age, [0, 120])) {
return age; // Valid age
}
throw new Error('Age must be a number between 0 and 120');
}Check if a string represents a valid number.
/**
* Check if string represents a valid number
* @param value - Value to check
* @returns True if value is numeric string
*/
function isNumericString(value: unknown): value is `${number}`;Usage Examples:
import is from '@sindresorhus/is';
is.numericString('42'); // => true
is.numericString('3.14'); // => true
is.numericString('-123'); // => true
is.numericString('1e10'); // => true
is.numericString('Infinity'); // => true
is.numericString('-Infinity'); // => true
is.numericString('NaN'); // => false
is.numericString('42px'); // => false
is.numericString(''); // => false
is.numericString(' '); // => false
is.numericString('hello'); // => false
// Type guard usage
function parseNumber(input: unknown) {
if (is.numericString(input)) {
// input is now typed as `${number}`
const num = Number(input);
return num;
}
throw new Error('Input is not a numeric string');
}
// Form validation
function validateFormInput(input: unknown) {
if (is.string(input) && is.numericString(input)) {
return Number(input);
}
return null;
}import is from '@sindresorhus/is';
function validatePositiveInteger(value: unknown): number {
if (!is.number(value)) {
throw new Error('Value must be a number');
}
if (!is.integer(value)) {
throw new Error('Value must be an integer');
}
if (!is.positiveNumber(value)) {
throw new Error('Value must be positive');
}
return value;
}
// Usage
try {
const count = validatePositiveInteger(42); // OK
const invalid = validatePositiveInteger(-5); // throws
} catch (error) {
console.error(error.message);
}import is from '@sindresorhus/is';
function factorial(n: unknown): number {
if (!is.number(n) || !is.integer(n) || !is.positiveNumber(n)) {
throw new Error('Factorial requires a positive integer');
}
if (n === 0) return 1;
return n * factorial(n - 1);
}
function gcd(a: unknown, b: unknown): number {
if (!is.integer(a) || !is.integer(b)) {
throw new Error('GCD requires integers');
}
const absA = Math.abs(a as number);
const absB = Math.abs(b as number);
return absB === 0 ? absA : gcd(absB, absA % absB);
}import is from '@sindresorhus/is';
function categorizeNumbers(numbers: unknown[]): {
positive: number[];
negative: number[];
zero: number[];
invalid: unknown[];
} {
const result = {
positive: [] as number[],
negative: [] as number[],
zero: [] as number[],
invalid: [] as unknown[]
};
for (const num of numbers) {
if (!is.number(num)) {
result.invalid.push(num);
} else if (is.positiveNumber(num)) {
result.positive.push(num);
} else if (is.negativeNumber(num)) {
result.negative.push(num);
} else {
result.zero.push(num); // Must be 0
}
}
return result;
}import is from '@sindresorhus/is';
function safeMath(a: unknown, b: unknown, operation: string): number {
if (!is.number(a) || !is.number(b)) {
throw new Error('Both operands must be numbers');
}
if (!is.safeInteger(a) || !is.safeInteger(b)) {
throw new Error('Operands must be safe integers');
}
let result: number;
switch (operation) {
case '+':
result = a + b;
break;
case '*':
result = a * b;
break;
default:
throw new Error('Unsupported operation');
}
if (!is.safeInteger(result)) {
throw new Error('Result exceeds safe integer range');
}
return result;
}isInteger() uses Number.isInteger() internallyisSafeInteger() checks if number is within Number.MAX_SAFE_INTEGER rangefalseisInRange() accepts the number to check as first parameter (must already be a number)'NaN' but includes 'Infinity' and '-Infinity'Install with Tessl CLI
npx tessl i tessl/npm-sindresorhus--is