Types
Superstruct exposes factory functions for a variety of common JavaScript (and TypeScript) types. You can also define your own custom validation functions using the struct
factory.
any
any
any()
'valid'
42
true
undefined
null
{
also: 'valid'
}
any
structs accept any value as valid.
🤖 Note that if you're using TypeScript, the
any
struct will loosen the type toany
, and you might want to useunknown
instead.
array
array
array(number())
array(object({ id: number() }))
[1, 2, 3]
[{ id: 1 }]
array
structs accept a list of values of a specific type.
bigint
bigint
bigint()
0n
3n
4000030n
BigInt(10n^1000n)
bigint
structs validate that a value is a bigint.
boolean
boolean
boolean()
true
false
boolean
structs accept the boolean values true
and false
.
date
date
date()
new Date()
date
structs accept JavaScript Date
instances.
🤖 To avoid unexpected runtime errors,
date
structs do not accept invalidDate
objects, even though they are technically an instance of aDate
. This meshes with the 99% use case where invalid dates create inconsistencies.
enums
enums
enums(['Jane', 'John', 'Jack', 'Jill'])
'Jane'
'John'
enums
structs validate that a value is one of a specific set of literals values.
func
func
func()
function () {}
func
structs validate that a value is a function.
instance
instance
instance(MyClass)
new MyClass()
instance
structs validate that a value is an instance of a particular class, using JavaScript's built-in instanceof
operator.
integer
integer
integer()
-7
0
42
integer
structs validate that a value is an integer.
intersection
intersection
intersection([string(), Email])
intersection
structs validate that a value matches all of many structs. It takes existing struct objects as arguments.
literal
literal
literal(42)
42
literal
structs enforce that a value matches an exact value using the ===
operator.
map
map
map(string(), number())
new Map([
['a', 1],
['b', 2],
])
map
structs validate that a value is a Map
object with specific types for its keys and values.
🤖 When defining a key/value schemas with
map
it will traverse all the properties to ensure they are valid! If you don't care about validating the properties of the map, you can writemap()
instead.
never
never
never()
never
structs will fail validation for every value.
number
number
number()
0
3.14
42
Infinity
number
structs validate that a value is a number.
nullable
nullable
nullable(string())
'a string of text'
null
nullable
structs validate that a value matches a specific struct, or that it is null
.
object
object
object({
id: number(),
name: string(),
})
{
id: 1,
name: 'Jane Smith',
}
object
structs validate that a value is an object and that each of its properties match a specific type as well.
🤖 Note that
object
structs throw errors if they encounter extra properties on an object, unlessmask
is used! If you want to be less strict and ignore any extra properties, usetype
instead. For other more complex object use cases, check out the coercions and utilities too.
optional
optional
optional(string())
'a string of text'
undefined
optional
structs validate that a value matches a specific struct, or that it is undefined
.
🤖 Warning: If you are using TypeScript, you must enable TypeScript's
strictNullChecks
option in yourtsconfig.json
for Superstruct to work properly with "optional" types. Note thatstrictNullChecks
is disabled by default. If you enablestrict
,strictNullChecks
will automatically be enabled.
record
record
record(string(), number())
{
a: 1,
b: 2,
}
record
structs validate an object with specific types for its keys and values. But, unlike object
structs, they do not enforce a specific set of keys.
regexp
regexp
regexp()
;/\d+/
new RegExp()
regexp
structs validate that a value is a RegExp
object.
🤖 This does not test the value against the regular expression! For that you want the
pattern
refinement.
set
set
set(string())
new Set(['a', 'b', 'c'])
set
structs validate that a value is a Set
instance with elements of a specific type.
🤖 When defining a child schema with
set
it will traverse all the children to ensure they are valid! If you don't care about validating the elements of the set, you can writeset()
instead.
string
string
string()
'a string of text'
string
structs validate that a value is a string.
tuple
tuple
tuple([string(), number(), boolean()])
['a', 1, true]
tuple
structs validate that a value is an array of a specific length with values each of a specific type.
type
type
type({
name: string(),
walk: func(),
})
{
name: 'Jill',
age: 37,
race: 'human',
walk: () => {},
}
type
structs validate that a value has a set of properties on it, but it does not assert anything about unspecified properties. This allows you to assert that a particular set of functionality exists without a strict equality check for properties.
When mask()
is used with a value of type
, its unknown properties are not removed. I.e. consider type
as a signal to the core that the object may have arbitrary properties in addition to the known ones, in both masked and non-masked validation.
🤖 If you want to throw errors when encountering unknown properties, use
object
instead.
union
union
union([string(), number()])
'a string'
42
union
structs validate that a value matches at least one of many types.
unknown
unknown
unknown()
'valid'
42
true
undefined
null
{
also: 'valid'
}
unknown
structs accept unknown value as valid without loosening its type to any
.
Custom Types
You can also define your own custom structs that are specific to your application's requirements, like so:
import { define } from 'superstruct'
import isEmail from 'is-email'
import isUuid from 'is-uuid'
const Email = define('Email', isEmail)
const Uuid = define('Uuid', (value) => isUuid.v4(value))
const User = object({
id: Uuid,
name: string(),
email: Email,
age: number(),
})
Custom types take validator functions that return either true/false
or an array of StructFailure
objects, in case you want to build more helpful error messages.
🤖 If you are using Typescript the value will be of type
unknown
by default. You can pass a more specific type for Typescript:const Email = define<string>('Email', isEmail)
Last updated