Isntnt is a collection of composable JavaScript runtime type predicates with TypeScript type guard declarations. Supports generics including union and intersection types.
Features
Predicates
A predicate is a function that checks whether a value matches a certain type, it always returns a boolean. Well known examples of JavaScript predicates are Array.isArray
, isNan
, and Number.isNaN
. With isntnt
you add a whole slew of additional predicates to your toolbox, they are listed below.
hasLength
Returns true
when you pass an object with a length property that is a valid length
.
hasLength(new ArrayBuffer())
hasLength({})
isAny
Always returns true
.
isAny(null)
isAny(12)
isArray
Returns true
when you pass an array.
isArray([])
isArray('foo')
isArrayLike
Returns true
when you pass a object that is not a function with a length property that is a valid length
.
isArrayLike({ length: 12 })
isArrayLike(new Date())
isBigInt
Returns true
when you pass a bigint.
isBigInt(116n)
isBigInt(12)
isBoolean
Returns true
when you pass a boolean.
isBoolean(true)
isBoolean(null)
isDate
Returns true
when you pass a Date object.
isDate(new Date())
isDate(Date.now())
isDictionary
Returns true
when you pass an object of which each property name, and each property value are a string.
isDictionary({ a: 'foo' })
isDictionary({ b: 12 })
isFalse
Returns true
when you pass false
.
isFalse(false)
isFalse(true)
isFunction
Returns true
when you pass a function.
isFunction(isFunction)
isFunction({})
isInt
Returns true
when you pass an integer (a whole number).
isInt(1)
isInt(1.5)
isInt8
Returns true
when you pass an integer ranging from -128 to 127.
isInt8(127)
isInt8(128)
isInt16
Returns true
when you pass an integer ranging from -32,768 to 32,767.
isInt16(12)
isInt16(-50_000)
isInt32
Returns true
when you pass an integer ranging from -2,147,483,648 to 2,147,483,647.
isInt32(12)
isInt32(Number.MAX_SAFE_INTEGER)
isLength
Alias to isUint32
.
isMap
Returns true
when you pas a Map object.
isMap(new Map())
isMap({})
isNegative
Returns true
when you pas a negative number (including -0).
isNegative(-1)
isNegative(1)
isNever
Always returns false
.
isNever(null)
isNever(true)
isNone
Returns true
when you pass null
or undefined
.
isNone(null)
isNone(128)
isNull
Returns true
when you pass null
.
isNull(null)
isNull(undefined)
isNumber
Returns true
when you pass a number that is not NaN
.
isNumber(12)
isNumber(NaN)
isObject
Returns true
when you pass an object that is not null
.
isObject({})
isObject(null)
isObjectLike
Returns true
when you pass an value that is not a boolean, null
, or undefined
.
isObjectLike([])
isObjectLike(true)
isPlainObject
Returns true
when you pass an object that was constructed by Object
.
isPlainObject({})
isPlainObject(new Date())
isPositive
Returns true
when you pass a positive number.
isPositive(1)
isPositive(-1)
isPrimitive
Returns true
when you pass null
, undefined
, a boolean, bigint, number, symbol, or string.
isPrimitive(1)
isPrimitive([])
isRegExp
Returns true
when you pass a RegExp object.
isRegExp(/foo/)
isRegExp([])
isSerializable
Returns true
when you pass a serializable primitive, a serializable array, or serializable object.
isSerializable(12)
isSerializable(console.log)
isSerializableArray
Returns true
when you pass an array where every element is serializable.
isSerializableArray(['foo', 1])
isSerializableArray([new Date()])
isSerializableNumber
Returns true
when you pass a number that is not NaN
, Infinity
, or -Infinity
.
isSerializableNumber(1)
isSerializableNumber(Infinity)
isSerializableObject
Returns true
when you pass an object where every property is serializable.
isSerializableObject({ foo: 1 })
isSerializableObject({ bar: Infinity })
isSerializablePrimitive
Returns true
when you pass null
, a serializable number, a boolean, bigint, symbol, or string.
isSerializablePrimitive(null)
isSerializablePrimitive(NaN)
isSet
Returns true
when you pas a Set object.
isSet(new Set())
isSet([])
isSome
Returns true
when you pas a value other than null
or undefined
.
isSome('foo')
isSome(null)
isString
Returns true
when you pas a string.
isString('bar')
isString(48)
isSymbol
Returns true
when you pas a symbol.
isSymbol(Symbol())
isSymbol('baz')
isTrue
Returns true
when you pas true
.
isTrue(true)
isTrue(false)
isUint
Returns true
when you pass a positive integer.
isUint(112)
isUint(-16)
isUint8
Returns true
when you pass an unsigned integer ranging from 0 to 255.
isUint8(255)
isUint8(1.2)
isUint16
Returns true
when you pass an unsigned integer ranging from 0 to 65,535.
isUint16(2048)
isUint16(-12)
isUint32
Returns true
when you pass an unsigned integer ranging from 0 to 4,294,967,295.
isUint32(256)
isUint(Number.MAX_SAFE_INTEGER)
isUndefined
Returns true
when you pass undefined
.
isUndefined(undefined)
isUndefined(null)
isWeakMap
Returns true
when you pass a WeakMap
object.
isWeakMap(new WeakMap())
isWeakMap(new Map())
Predicate factories
Predicate factories is where the real fun begins, they allow you to create and combine predicates of your own to create new predicates. By composing predicates you can describe objects, union types, number ranges, and so on.
above
Create a predicate based on a floor value, it checks if a number exceeds the floor value it’s given. This is an analogue to the >
operator.
const isAboveZero = above(0)
isAboveZero(-1)
isAboveZero(12)
The isAboveZero
predicate above returns true
when you pass a number that is greater than 0
.
and
Create a predicate based on several other predicates, it returns true
if every predicate that is passed also returns true
. This is an analogue to the &&
operator.
const adultAge = 18
const isMinorAge = and(isUint, below(adultAge))
isMinorAge(12)
isMinorAge(33)
The isMinorAge
predicate above returns true
when you pass an unsigned integer that is below 18.
const isUser = shape({ name: isString })
const hasEmailAddress = shape({ email: isString })
const isUserWithEmail = and(isUser, hasEmailAddress)
The isUserWithEmail
predicate above returns true
when you pass an object with a name
and an email
property, both of which are a string.
array
Create a predicate that checks every array element, it returns true
when its predicate returns true
for every element in an array.
const isNumberArray = array(isNumber)
The isNumberArray
predicate above returns true
when you pass an array of which every element is a number.
at
Create a predicate based on a property key and another predicate, it returns true
when its predicate returns true
for the value of an object at its given key.
const isStringAtName = at('name', isString)
isStringAtName({ name: 'Jane' })
isStringAtName({ name: null })
The isStringAtName
predicate above returns true
when you pass an object of which the name
property is a string.
below
Create a predicate based on a ceiling value, it checks if a number is below the ceiling value it’s given. This is an analogue to the <
operator.
const isBelow100 = below(100)
isBelow100(124)
isBelow100(32)
The isBelow100
predicate above returns true
when you pass a number that is less than 100
.
either
Create a predicate based on several literal values, it returns true
if a value matches either of the primitive values it’s given.
const isAOrB = either('a', 'b')
isAOrB('a')
isAOrB('c')
The isAOrB
predicate above returns true
when you pass either a
, or b
.
has
Create a predicate based on a property key, it returns true
if an object has a property of the key it’s given.
const hasName = has('name')
hasName({ name: null })
hasName({ age: 36 })
The hasName
predicate above returns true
when you pass an object that has a name
property.
instance
Create a predicate based on a constructor, it returns true
if an object is an instance of the constructor key it’s given.
const isInstanceofString = instance(String)
isInstanceofString(new String('foo'))
isInstanceofString('foo')
The isInstanceofString
predicate above returns true
when you pass a String object.
literal
Create a predicate based a primitive value, it returns true
if a value equals the primitive value it’s given.
const is42 = literal(42)
is42(42)
is42(43)
The is42
predicate above returns true
when you pass 42
.
max
Create a predicate based on a max. value, it checks if a number is below or equal to the max. value it’s given. This is an analogue to the <=
operator.
const isMax100 = max(100)
isMax100(100)
isMax100(101)
The isMax100
predicate above returns true
when you pass a number that is below or equal to 100
.
maybe
Create a predicate based on another predicate, it checks if a value matches it’s given predicate, or equals null
or undefined
.
const isMaybeString = maybe(isString)
isMaybeString(null)
isMaybeString(12)
The isMaybeString
predicate above returns true
when you pass a string, null
, or undefined
.
min
Create a predicate based on a min. value, it checks if a number is above or equal to the min. value it’s given. This is an analogue to the >=
operator.
const isMin100 = min(100)
isMin100(100)
isMin100(99)
The isMin0
predicate above returns true
when you pass a number that is above or equal to 100
.
noneable
Aliases maybe
.
nullable
Create a predicate based on another predicate, it checks if a value matches it’s given predicate, or equals null
.
const isNullableString = nullable(isString)
isNullableString(null)
isNullableString(12)
The isNullableString
predicate above returns true
when you pass a string or null
.
object
Create a predicate that checks every object property, it returns true
when its predicate returns true
for every object value.
const isEnumerable = object(isUint)
The isEnumerable
predicate above returns true
when you pass an object of which every element is an unsigned integer.
optional
<T>(predicate: Predicate<T>) => (value: unknown) => value is T | undefined
const isOptionalString = optional(isString)
isOptionalString(undefined)
isOptionalString(12)
The isOptionalString
predicate above returns true
when you pass a string or undefined
.
or
Create a predicate based on several other predicates, it returns true
if some predicate that is passed also returns true
. This is an analogue to the ||
operator.
const isContent = or(isString, isSerializableNumber)
isContent(12)
isContent(null)
The isContent
predicate above returns true
when you pass a string or a primitive number.
const isStringOrNumber = or(isString, isNumber)
isStringOrNumber(8)
isStringOrNumber([])
record
Create a predicate based on a key predicate and a value predicate, it returns true
if each property key of an object returns true
for its key predicate, and each value returns true
for its value predicate.
const isValidKey = either('a', 'b')
const isKeyValueMap = record(isValidKey, isInt)
isKeyValueMap({ a: 2 })
isKeyValueMap({ a: null })
isKeyValueMap({ c: 2 })
The isKeyValueMap
predicate above returns true
when you pass an object where each key is either a
or b
, and each property value is an integer.
shape
Create a predicate based on a predicate object, it returns true
if each property value of an object returns true
for its corresponding predicate.
const isPoint = shape({ x: isNumber, y: isNumber })
isPoint({ x: 12, y: 36 })
isPoint({ x: 12 })
The isPoint
predicate above returns true
when you an pass an object where both x
and y
properties are a number.
test
const isSlug = test(/^[A-Z0-9-]+$/i)
isSlug('foo-bar')
isSlug('!#$')
The isSlug
predicate above returns true
when you an pass a string that matches /^[A-Z0-9-]+$/i
.
tuple
Create a predicate based on index-based predicates, it returns true
if the element at each index of an array with a fixed length returns true
for its corresponding predicate.
const isLatitude = and(min(-90), max(90))
const isLongitude = and(min(-180), max(180))
const isLatLong = tuple(isLatitude, isLongitude)
isLatLong(45, -120)
isLatLong(120, 200)
The isLatLong
predicate above returns true
when you an pass an array with a length of 2 where index 0 is a latitude, and index 1 is a longitude value.
Types
Intersect
type User = Intersect<{ name: string } | { email: string }>
Maybe
Unions a type with null
and undefined
.
type MaybeString = Maybe<string>
None
Union of null
and undefined
.
type X = None
Nullable
Unions a type with null
.
type NullableString = Nullable<string>
Optional
Unions a type with undefined
.
type OptionalString = Optional<string>
Predicate
Describes a predicate function signature
type IsString = Predicate<string>
Primitive
Union of all primitive types.
type X = Primitive
Serializable
type X = Serializable
SerializableArray
type X = SerializableArray
SerializableObject
type X = SerializableObject
SerializablePrimitive
type X = SerializablePrimitive
Some
Excludes null
and undefined
from a type, type parameter is optional.
type X = Some
type Y = Some<string | null>
Static
Extracts type parameter from Predicate type. This is useful to extract TypeScript types from (complex) predicates.
type X = Static<Predicate<string>>>