Data Types
Primitives
Primitive types represent primitive values, which are immutable and have no properties:
parseString('hello') // -> ParseSuccess
parseNumber(42) // -> ParseSuccess
parseBoolean(true) // -> ParseSuccess
parseNull(null) // -> ParseSuccess
parseUndefined(undefined) // -> ParseSuccess
parseBigInt(42n) // -> ParseSuccess
parseSymbol(Symbol()) // -> ParseSuccessisString('hello') // -> true
isNumber(42) // -> true
isBoolean(true) // -> true
isNull(null) // -> true
isUndefined(undefined) // -> true
isBigInt(42n) // -> true
isSymbol(Symbol()) // -> truePrimitive Literals (equals)
Primitive literals such as true, false, 42, "hello", and null are all types and values (depending on the context they appear in). Use the equalsGuard() function to create a guard function that compares the data with the strict equality operator (===):
const parseRed = equals('red')
parseRed('red') // -> ParseSuccess<'red'>
parseRed('blue') // -> ParseError
const parseOne = equals(1)
parseOne(1) // -> ParseSuccess<1>
parseOne(2) // -> ParseErrorconst isRed = equalsGuard('red')
isRed('red') // -> true
isRed('blue') // -> false
const isOne = equalsGuard(1)
isOne(1) // -> true
isOne(2) // -> falseTo validate a union of literals, use oneOf:
const parseDirection = oneOf(
equals('north'),
equals('south'),
equals('east'),
equals('west'),
)
parseDirection('north') // -> ParseSuccess<'north' | 'south' | 'east' | 'west'>
parseDirection('up') // -> ParseError
const parseDigit = oneOf(
equals(0),
equals(1),
equals(2),
equals(3),
equals(4),
equals(5),
equals(6),
equals(7),
equals(8),
equals(9),
)
parseDigit(5) // -> ParseSuccess<0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9>
parseDigit(50) // -> ParseErrorconst isDirection = oneOfGuard(
equals('north'),
equals('south'),
equals('east'),
equals('west'),
)
isDirection('north') // -> true
isDirection('east') // -> true
const isDigit = oneOfGuard(
equalsGuard(0),
equalsGuard(1),
equalsGuard(2),
equalsGuard(3),
equalsGuard(4),
equalsGuard(5),
equalsGuard(6),
equalsGuard(7),
equalsGuard(8),
equalsGuard(9),
)
isDigit(5) // -> true
isDigit(100) // -> falseUnions
Unions types—or sum types—represent values that can be one of several types. Use the oneOf() function to create a validation function for a union type:
const parseStringOrNumber = oneOf(parseString, parseNumber)
parseStringOrNumber('hello') // -> ParseSuccess
parseStringOrNumber(123) // -> ParseSuccessconst isStringOrNumber = unionGuard(isString, isNumber)
isStringOrNumber('hello') // -> true
isStringOrNumber(123) // -> trueSince it is very common to create unions with null and undefined, there are two helper functions for validating optional and nullable types:
undefineable/undefineableGuard—for unions withundefinednullable/nullableGuard—for unions withnull
const parseUndefineableString = undefineable(parseString)
parseOptionalString('hello') // -> ParseSuccess<string | undefined>
parseOptionalString(undefined) // -> ParseSuccess<string | undefined>
const parseNullableString = optional(parseString)
parseNullableString('hello') // -> ParseSuccess<string | null>
parseNullableString(null) // -> ParseSuccess<string | null>const isUndefineableString = undefineableGuard(isString)
isOptionalString('hello') // -> true
isOptionalString(undefined) // -> true
const isNullableString = optionalGuard(isString)
isNullableString('hello') // -> true
isNullableString(null) // -> trueTuples
Tuples are arrays of fixed length, where each element has a specific type. Use the tuple() function to create a parser function for a tuple type:
import { tupleGuard as tuple } from 'pure-parse'
const parseCoordinate = tuple([parseNumber, parseNumber])
parseCoordinate([42, 34]) // -> ParseSuccess
const parseTransparentColor = tuple([parseString, parseNumber])
parseTransparentColor(['#FF0000', 0.5]) // -> ParseSuccessconst isCoordinate = tupleGuard([isNumber, isNumber])
isCoordinate([42, 34]) // -> true
const isTransparentColor = tupleGuard([isString, isNumber])
isTransparentColor(['#FF0000', 0.5]) // -> trueObjects
Validate objects with object/objectGuard which takes an object as argument, with keys and corresponding validation functions:
const parseUser = object({
id: parseNumber,
name: parseString,
})
parseUser({ id: 42, name: 'Alice' }) // -> ParseSuccessconst isUser = objectGuard({
id: isNumber,
name: isString,
})
isUser({ id: 42, name: 'Alice' }) // -> trueYou can nest objects:
const parseUser = object({
id: parseNumber,
name: parseString,
address: object({
country: parseString,
city: parseString,
streetAddress: parseString,
zipCode: parseNumber,
}),
})const isUser = objectGuard({
id: isNumber,
name: isString,
address: objectGuard({
country: isString,
city: isString,
streetAddress: isString,
zipCode: isNumber,
}),
})You can declare optional properties:
const parseUser = object({
id: parseNumber,
name: optional(parseString),
})
parseUser({ id: 42 }) // -> ParseSuccess
parseUser({ id: 42, name: undefined }) // -> ParseSuccess
parseUser({ id: 42, name: 'Jiří' }) // -> ParseSuccessconst isUser = objectGuard({
id: isNumber,
name: optionalGuard(isString),
})
isUser({ id: 42 }) // -> true
isUser({ id: 42, name: undefined }) // -> true
isUser({ id: 42, name: 'Jiří' }) // -> trueYou can explicitly declare the type of the object and annotate the validation function with the type as a type parameter:
type User = {
id: number
name?: string
}
const parseUser = object<User>({
id: parseNumber,
name: optional(parseString),
})type User = {
id: number
name?: string
}
const isUser = objectGuard<User>({
id: isNumber,
name: optionalGuard(isString),
})Arrays
Use array/arrayGuard to validate arrays:
const parseBase = oneOf(equals('A'), equals('T'), equals('C'), equals('G'))
const parseDna = array(parseBase)
parseDna(['A', 'T', 'A', 'T', 'C', 'G']) // -> ParseSuccessconst isBase = oneOf(
equalsGuard('A'),
equalsGuard('T'),
equalsGuard('C'),
equalsGuard('G'),
)
const isDna = arrayGuard(isBase)
isDna(['A', 'T', 'A', 'T', 'C', 'G']) // -> trueWhen explicitly declaring array types, provide type of the item in the array type argument:
// Validator<number[]>
const parseNumberArray = array<number>(parseNumber)Tagged/Discriminated Unions
Validate discriminated unions by combining oneOf with object:
const parseState = oneOf(
object({
tag: equals('loading'),
}),
object({
tag: equals('error'),
error: parseString,
}),
object({
tag: equals('loaded'),
message: parseString,
}),
)
parseState({ tag: 'loading' }) // -> ParseSuccess
parseState({ tag: 'error', error: 'Failed to load' }) // -> ParseSuccess
parseState({ tag: 'loaded', message: 'Data loaded' }) // -> ParseSuccessconst isState = unionGuard(
objectGuard({
tag: equalsGuard('loading'),
}),
objectGuard({
tag: equalsGuard('error'),
error: isString,
}),
objectGuard({
tag: equalsGuard('loaded'),
message: isString,
}),
)
isState({ tag: 'loading' }) // -> true
isState({ tag: 'error', error: 'Failed to load' }) // -> true
isState({ tag: 'loaded', message: 'Data loaded' }) // -> true