Type guards
js
import { isDefined, isNumber, isObject, isString } from '@studiometa/js-toolkit-v4/utils';Each one narrows the type.
| Function | Signature |
|---|---|
isNull(value) | value is null |
isDefined(value) | value is T — for T | undefined |
isString(value) | value is string |
isNumber(value) | value is number |
isBoolean(value) | value is boolean |
isFunction(value) | value is (...args: unknown[]) => unknown |
isObject(value) | value is Record<string, unknown> |
Usage
ts
import { isDefined, isObject, isString } from '@studiometa/js-toolkit-v4/utils';
function label(value: unknown): string {
if (isString(value)) return value; // string
if (isObject(value)) return JSON.stringify(value); // Record<string, unknown>
return '';
}
function first<T>(items: (T | undefined)[]): T[] {
return items.filter(isDefined); // T[]
}isDefined as a filter predicate is the case that earns the export: it is the one narrowing TypeScript will not do from a truthiness check.
isNumber rejects NaN
js
isNumber(NaN); // falseBecause a NaN that passes a number check is a bug that surfaces three functions later.
What is not here
| Not shipped | Write |
|---|---|
isArray | Array.isArray(value) |
isEmpty | the check the caller actually means |
isEmptyString | value === '' |
isDev | your bundler's own flag |
A guard earns its place by narrowing something the platform does not, or by being a predicate you pass by reference.