Primitives
TypeScript has a set of primitive types that are built-in to the language. They are the building blocks of all other types.
type-plus provides a set of utilities to help you work with these types.
Each primitive type has an identifying util so that you can pinpoint them and process them specifically, as well as a other utilities that are useful for working with them.
anyunknownnevervoidundefinednullfunctionbooleanstringnumberbigintsymbolobjectarraytuple
The predicates for most of those types live on their own pages. This page covers the rest: the special
types any, unknown, never and void, and the unit types null, undefined and symbol.
The special types
Section titled “The special types”any, unknown, never and void do not behave like other types in a conditional type. A union with
any or unknown collapses into it, a union drops never, and any takes both branches of a check.
Every Is* predicate in the library routes these four through its $any, $unknown, $never and
$void options for that reason (see type branching). The predicates
below check for the special types themselves.
IsAny and IsNotAny
Section titled “IsAny and IsNotAny”type IsAny<T, $O extends $StrictOptions<$O, IsAny.$Options> = {}>type IsNotAny<T, $O extends $StrictOptions<$O, IsNotAny.$Options> = {}>🎭 predicate — T is (not) any.
import type { IsAny, IsNotAny } from 'type-plus'
type R = IsAny<any> // truetype R = IsAny<unknown> // falsetype R = IsAny<never> // falsetype R = IsAny<any | 1> // true, the union is `any`
type R = IsNotAny<unknown, { selection: 'filter' }> // unknowntype R = IsAny<unknown, IsAny.$Branch> // $UnknownA union with any is any, so there is no HasAny: it would be IsAny.
IsUnknown and IsNotUnknown
Section titled “IsUnknown and IsNotUnknown”type IsUnknown<T, $O extends $StrictOptions<$O, IsUnknown.$Options> = {}>type IsNotUnknown<T, $O extends $StrictOptions<$O, IsNotUnknown.$Options> = {}>🎭 predicate — T is (not) exactly unknown.
import type { IsNotUnknown, IsUnknown } from 'type-plus'
type R = IsUnknown<unknown> // truetype R = IsUnknown<number> // falsetype R = IsUnknown<never> // false
type R = IsNotUnknown<number, { selection: 'filter' }> // numberNotUnknownOr
Section titled “NotUnknownOr”type NotUnknownOr<T, $O extends $StrictOptions<$O, NotUnknownOr.$Options> = {}>🌪️ filter — T when it is not unknown, otherwise $Unknown, or the $unknown option when given.
import type { NotUnknownOr } from 'type-plus'
type R = NotUnknownOr<number> // numbertype R = NotUnknownOr<unknown> // $Unknowntype R = NotUnknownOr<unknown, { $unknown: number }> // numberUse it to give an unconstrained type parameter a fallback without testing it first.
IsNever and IsNotNever
Section titled “IsNever and IsNotNever”type IsNever<T, $O extends $StrictOptions<$O, IsNever.$Options> = {}>type IsNotNever<T, $O extends $StrictOptions<$O, IsNotNever.$Options> = {}>🎭 predicate — T is (not) never.
import type { IsNever, IsNotNever } from 'type-plus'
type R = IsNever<never> // truetype R = IsNever<1> // falsetype R = IsNever<never | 1> // false, the union drops `never`A filter usually returns never when the check fails. That is the value these two check for, so their
filters return a marker instead: IsNever returns $NotNever and IsNotNever returns $Never.
type R = IsNever<never, { selection: 'filter' }> // nevertype R = IsNever<1, { selection: 'filter' }> // $NotNever
type R = IsNotNever<1, { selection: 'filter' }> // 1type R = IsNotNever<never, { selection: 'filter' }> // $NeverA union drops never, so there is no HasNever: it would be IsNever. To test for any and never in
one step, use IsAnyOrNever.
IsVoid and IsNotVoid
Section titled “IsVoid and IsNotVoid”type IsVoid<T, $O extends $StrictOptions<$O, IsVoid.$Options> = {}>type IsNotVoid<T, $O extends $StrictOptions<$O, IsNotVoid.$Options> = {}>🎭 predicate — T is (not) void. undefined is not void.
import type { IsNotVoid, IsVoid } from 'type-plus'
type R = IsVoid<void> // truetype R = IsVoid<undefined> // falsetype R = IsVoid<string | void> // booleantype R = IsVoid<void | 1, { distributive: false }> // false
type R = IsNotVoid<string | void, { selection: 'filter' }> // stringnull, undefined and symbol
Section titled “null, undefined and symbol”IsNull, IsUndefined, IsSymbol and their negations
Section titled “IsNull, IsUndefined, IsSymbol and their negations”type IsNull<T, $O extends $StrictOptions<$O, IsNull.$Options> = {}>type IsNotNull<T, $O extends $StrictOptions<$O, IsNotNull.$Options> = {}>type IsUndefined<T, $O extends $StrictOptions<$O, IsUndefined.$Options> = {}>type IsNotUndefined<T, $O extends $StrictOptions<$O, IsNotUndefined.$Options> = {}>type IsSymbol<T, $O extends $StrictOptions<$O, IsSymbol.$Options> = {}>type IsNotSymbol<T, $O extends $StrictOptions<$O, IsNotSymbol.$Options> = {}>🎭 predicate — T is (not) null, undefined or symbol. They distribute over a union, so a union
that holds the type only in part yields boolean.
import type { IsNotNull, IsNull, IsSymbol, IsUndefined } from 'type-plus'
type R = IsNull<null> // truetype R = IsNull<string | null> // booleantype R = IsNull<string | null, { selection: 'filter' }> // nulltype R = IsNotNull<string | null, { selection: 'filter' }> // string
type R = IsUndefined<undefined> // truetype R = IsUndefined<void> // false
type R = IsSymbol<symbol> // truetype R = IsSymbol<symbol | 1, { distributive: false }> // falseHasNull, HasUndefined, HasVoid and their negations
Section titled “HasNull, HasUndefined, HasVoid and their negations”type HasNull<T, $O extends $StrictOptions<$O, HasNull.$Options> = {}>type HasNoNull<T, $O extends $StrictOptions<$O, HasNoNull.$Options> = {}>type HasUndefined<T, $O extends $StrictOptions<$O, HasUndefined.$Options> = {}>type HasNoUndefined<T, $O extends $StrictOptions<$O, HasNoUndefined.$Options> = {}>type HasVoid<T, $O extends $StrictOptions<$O, HasVoid.$Options> = {}>type HasNoVoid<T, $O extends $StrictOptions<$O, HasNoVoid.$Options> = {}>🎭 predicate — T is the type, or a union that contains it. Where IsNull<string | null> yields
boolean, HasNull judges the union as a whole and yields true. The filter keeps the whole union.
import type { HasNoNull, HasNull, HasUndefined } from 'type-plus'
type R = HasNull<null> // truetype R = HasNull<null | 1> // truetype R = HasNull<number> // falsetype R = HasNull<null | 1, { selection: 'filter' }> // null | 1
type R = HasNoNull<1 | 2> // truetype R = HasNoNull<null | 1> // false
type R = HasUndefined<undefined | 1> // trueUse a Has* check to decide whether a type is nullable or optional; use an Is* check to pick the
matching members out of a union.
Reference
Section titled “Reference”| Type | Description |
|---|---|
IsAny / IsNotAny |
T is (not) any |
IsUnknown / IsNotUnknown |
T is (not) exactly unknown |
NotUnknownOr<T, $O> |
T, or a fallback when T is unknown |
IsNever / IsNotNever |
T is (not) never |
IsVoid / IsNotVoid |
T is (not) void |
IsNull / IsNotNull |
T is (not) null |
IsUndefined / IsNotUndefined |
T is (not) undefined |
IsSymbol / IsNotSymbol |
T is (not) symbol |
HasNull / HasNoNull |
T is (not) null or a union with null |
HasUndefined / HasNoUndefined |
T is (not) undefined or a union with undefined |
HasVoid / HasNoVoid |
T is (not) void or a union with void |
See Options for selection and distributive.