Skip to content

Type guards

js
import { 
isDefined
,
isNumber
,
isObject
,
isString
} from '@studiometa/js-toolkit/utils';

Each one narrows the type.

Usage

ts
import { 
isDefined
,
isObject
,
isString
} from '@studiometa/js-toolkit/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.

The guards

isNull

ts
isNull(value: unknown): value is null

isDefined

ts
isDefined<T>(value: T | undefined): value is T

Narrows T | undefined to T. Passing it by reference to filter is what it is for.

isString

ts
isString(value: unknown): value is string

isNumber

ts
isNumber(value: unknown): value is number

It rejects NaN, because a NaN that passes a number check is a bug that surfaces three functions later.

isBoolean

ts
isBoolean(value: unknown): value is boolean

isFunction

ts
isFunction(value: unknown): value is (...args: unknown[]) => unknown

isObject

ts
isObject(value: unknown): value is Record<string, unknown>

What is not here

Not shippedWrite
isArrayArray.isArray(value)
isEmptythe check the caller actually means
isEmptyStringvalue === ''
isDevyour 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.

MIT Licensed