Superstruct allows you to constrain existing structs with further validation. This doesn't change the type of the struct, but simply introduces extra validation logic. This can be useful for example when ensuring that a string matches a specific RegExp
.
empty(string())empty(array())
''[]
empty
enforces that a string
, array
, map
, or set
is empty.
🤖 Technically this is the same as using
size
of zero, but "empty" feels slightly nicer and will give a slightly easier to read error.
min(number(), 9000)
9001
min
enforces that a number
struct is greater than a threshold.
🤖 If you need an exclusive minimum you can pass
{ exclusive: true }
as the third argument, likemin(number(), 0, { exclusive: true })
for negative numbers.
max(number(), 0)
-1
max
enforces that a number
struct is less than a threshold.
🤖 If you need an exclusive maxmimum you can pass
{ exclusive: true }
as the third argument, likemax(number(), 0, { exclusive: true })
for positive numbers.
pattern(string(), /\d+/)
'123'
pattern
enforces that a string
struct also matches a supplied RegExp
.
size(string(), 1, 100)size(array(number), 0)size(number(), 93, Infinity)
'a string of text'[1, 2, 3]Infinity
size
enforces that a number
, string
, array
, map
, or set
struct also is within a certain min
and max
size (or length).
🤖 The
max
argument is optional and defaults to whatever you pass formin
, which makes specifying exact sizes easy (just omit the max).
You can also define your own custom refinments that are specific to your application's requirements, like so:
import { number, refine } from 'superstruct'​const PositiveInteger = refine(number(), 'PositiveInteger', (value) => {return Number.isInteger(value) && value >= 0})
This allows you to define more fine-grained runtime validation, while still preserving the number
type at compile time.