Table of contents
- any
- array
- ArrayOfValidator
- bigint
- boolean
- DictValidator
- httpUrl
- indexKey
- integer
- jsonValue
- linkUrl
- nonZeroFiniteNumber
- nonZeroInteger
- nonZeroNumber
- number
- ObjectValidator
- positiveInteger
- positiveNumber
- srcUrl
- string
- TypeOf
- UnionValidator
- UnionValidatorConfig
- unitInterval
- unknown
- unknownObject
- Validatable
- ValidationError
- Validator
- ValidatorFn
- ValidatorUsingKnownGoodVersionFn
- Properties
- Methods
Properties
any
Validator that accepts any value and types it as 'any'. This should generally be avoided as it bypasses type safety, but can be used as an escape hatch for prototyping.
any: Validator<any>Example
const result = T.any.validate(anything) // Returns the value as any
// result is typed as any - use with caution!array
Validator that ensures a value is an array. Does not validate the contents of the array. Use T.arrayOf() to validate both the array structure and its contents.
array: Validator<unknown[]>Example
const items = T.array.validate([1, 'hello', true]) // Returns unknown[]
T.array.validate('not array') // Throws ValidationError: "Expected an array, got a string"
// For typed arrays, use T.arrayOf:
const numbers = T.arrayOf(T.number).validate([1, 2, 3]) // Returns number[]ArrayOfValidator
Validator for arrays where each element is validated using the provided item validator. Extends the base Validator class with array-specific validation methods.
class ArrayOfValidator<T> extends Validator<T[]> {}Example
const stringArray = new ArrayOfValidator(T.string)
const numbers = stringArray.validate(['a', 'b', 'c']) // Returns string[]
const userArray = T.arrayOf(T.object({ name: T.string, age: T.number }))bigint
Validator that ensures a value is a bigint.
bigint: Validator<bigint>Example
const largeNumber = T.bigint.validate(123n) // Returns 123n
T.bigint.validate(123) // Throws ValidationError: "Expected bigint, got a number"boolean
Validator that ensures a value is a boolean.
boolean: Validator<boolean>Example
const isActive = T.boolean.validate(true) // Returns true
const isEnabled = T.boolean.validate(false) // Returns false
T.boolean.validate('true') // Throws ValidationError: "Expected boolean, got a string"DictValidator
Validator for dictionary/map objects where both keys and values are validated. Useful for validating objects used as key-value stores.
class DictValidator<Key extends string, Value> extends Validator<
Record<Key, Value>
> {}Example
const scoreDict = new DictValidator(T.string, T.number)
const scores = scoreDict.validate({
alice: 100,
bob: 85,
charlie: 92,
})
// scores is typed as Record<string, number>httpUrl
Validator for HTTP and HTTPS URLs only. Rejects all other protocols.
httpUrl: Validator<string>Example
const apiUrl = T.httpUrl.validate('https://api.example.com') // Valid
const httpUrl = T.httpUrl.validate('http://localhost:3000') // Valid
T.httpUrl.validate('') // Valid (empty string allowed)
T.httpUrl.validate('ftp://files.example.com') // Throws ValidationError (not http/https)indexKey
Validator for IndexKey values used in tldraw's indexing system. An IndexKey is a string that meets specific format requirements for use as a database index.
indexKey: Validator<IndexKey>Example
const key = T.indexKey.validate('valid_index_key') // Returns IndexKey
T.indexKey.validate('invalid key!') // Throws ValidationError (invalid format)integer
Validator that ensures a value is an integer (whole number).
integer: Validator<number>Example
const count = T.integer.validate(42) // Returns 42
T.integer.validate(3.14) // Throws ValidationError: "Expected an integer, got 3.14"
T.integer.validate(-5) // Returns -5 (negative integers are valid)jsonValue
Validator that ensures a value is valid JSON (string, number, boolean, null, array, or plain object). Rejects functions, undefined, symbols, and other non-JSON values.
jsonValue: Validator<JsonValue>Example
const data = T.jsonValue.validate({
name: 'Alice',
scores: [1, 2, 3],
active: true,
})
T.jsonValue.validate(undefined) // Throws ValidationError
T.jsonValue.validate(() => {}) // Throws ValidationErrorlinkUrl
Validator for URLs that are safe to use as user-facing links. Accepts http, https, and mailto protocols. This validator provides security by rejecting potentially dangerous protocols like javascript:.
linkUrl: Validator<string>Example
const link = T.linkUrl.validate('https://example.com') // Valid
const email = T.linkUrl.validate('mailto:user@example.com') // Valid
T.linkUrl.validate('') // Valid (empty string allowed)
T.linkUrl.validate('javascript:alert(1)') // Throws ValidationError (unsafe protocol)nonZeroFiniteNumber
Validator that ensures a value is a finite, non-zero number. Allows negative numbers. Useful for scale factors that can be negative (for flipping) but not zero.
nonZeroFiniteNumber: Validator<number>Example
const scale = T.nonZeroFiniteNumber.validate(-1.5) // Returns -1.5 (valid, allows negative)
T.nonZeroFiniteNumber.validate(0) // Throws ValidationError: "Expected a non-zero number, got 0"
T.nonZeroFiniteNumber.validate(Infinity) // Throws ValidationErrornonZeroInteger
Validator that ensures a value is a positive integer (> 0). Rejects zero and negative integers.
nonZeroInteger: Validator<number>Example
const itemCount = T.nonZeroInteger.validate(1) // Returns 1
T.nonZeroInteger.validate(0) // Throws ValidationError: "Expected a non-zero positive integer, got 0"
T.nonZeroInteger.validate(-5) // Throws ValidationError: "Expected a non-zero positive integer, got -5"nonZeroNumber
Validator that ensures a value is a positive number (> 0). Rejects zero and negative numbers.
nonZeroNumber: Validator<number>Example
const quantity = T.nonZeroNumber.validate(0.01) // Returns 0.01
T.nonZeroNumber.validate(0) // Throws ValidationError: "Expected a non-zero positive number, got 0"
T.nonZeroNumber.validate(-5) // Throws ValidationError: "Expected a non-zero positive number, got -5"number
Validator that ensures a value is a finite, non-NaN number. Rejects Infinity, -Infinity, and NaN.
number: Validator<number>Example
const count = T.number.validate(42) // Returns 42 as number
T.number.validate(NaN) // Throws ValidationError: "Expected a number, got NaN"
T.number.validate(Infinity) // Throws ValidationError: "Expected a finite number, got Infinity"ObjectValidator
Validator for objects with a defined shape. Each property is validated using its corresponding validator from the config object. Can be configured to allow or reject unknown properties.
class ObjectValidator<Shape extends object> extends Validator<Shape> {}Example
const userValidator = new ObjectValidator({
name: T.string,
age: T.number,
email: T.string.optional(),
})
const user = userValidator.validate({
name: 'Alice',
age: 25,
email: 'alice@example.com',
})positiveInteger
Validator that ensures a value is a non-negative integer (>= 0). Despite the name "positive", this validator accepts zero.
positiveInteger: Validator<number>Example
const index = T.positiveInteger.validate(5) // Returns 5
const start = T.positiveInteger.validate(0) // Returns 0 (valid)
T.positiveInteger.validate(-1) // Throws ValidationError: "Expected a positive integer, got -1"
T.positiveInteger.validate(3.14) // Throws ValidationError: "Expected an integer, got 3.14"positiveNumber
Validator that ensures a value is a non-negative number (>= 0). Despite the name "positive", this validator accepts zero.
positiveNumber: Validator<number>Example
const price = T.positiveNumber.validate(29.99) // Returns 29.99
const free = T.positiveNumber.validate(0) // Returns 0 (valid)
T.positiveNumber.validate(-1) // Throws ValidationError: "Expected a positive number, got -1"srcUrl
Validator for URLs that are safe to use as asset sources. Accepts http, https, data, and asset protocols. The asset: protocol refers to tldraw's local IndexedDB object store.
srcUrl: Validator<string>Example
const imageUrl = T.srcUrl.validate('https://example.com/image.png') // Valid
const dataUrl = T.srcUrl.validate('data:image/png;base64,iVBORw0...') // Valid
const assetUrl = T.srcUrl.validate('asset:abc123') // Valid (local asset reference)
T.srcUrl.validate('') // Valid (empty string allowed)string
Validator that ensures a value is a string.
string: Validator<string>Example
const name = T.string.validate('hello') // Returns "hello" as string
T.string.validate(123) // Throws ValidationError: "Expected string, got a number"TypeOf
Utility type that extracts the validated type from a Validatable object. Useful for deriving TypeScript types from validator definitions.
type TypeOf<V extends Validatable<any>> =
V extends Validatable<infer T> ? T : neverExample
const userValidator = T.object({ name: T.string, age: T.number })
type User = TypeOf<typeof userValidator> // { name: string; age: number }UnionValidator
Validator for discriminated union types. Validates objects that can be one of several variants, distinguished by a discriminator property (key) that indicates which variant the object represents.
class UnionValidator<
Key extends string,
Config extends UnionValidatorConfig<Key, Config>,
UnknownValue = never,
> extends Validator<TypeOf<Config[keyof Config]> | UnknownValue> {}Example
const shapeValidator = new UnionValidator(
'type',
{
circle: T.object({ type: T.literal('circle'), radius: T.number }),
square: T.object({ type: T.literal('square'), size: T.number }),
},
() => {
throw new Error('Unknown shape')
},
false
)
const circle = shapeValidator.validate({ type: 'circle', radius: 5 })
// circle is typed as { type: 'circle'; radius: number }UnionValidatorConfig
Configuration type for union validators. Each variant must be a validator that produces an object with the discriminator key set to the variant name.
type UnionValidatorConfig<Key extends string, Config> = {
readonly [Variant in keyof Config]: Validatable<any> & {
validate(input: any): {
readonly [K in Key]: Variant
}
}
}Example
type ShapeConfig = UnionValidatorConfig<
'type',
{
circle: Validatable<{ type: 'circle'; radius: number }>
square: Validatable<{ type: 'square'; size: number }>
}
>unitInterval
Validator that ensures a value is a number in the unit interval [0, 1]. Useful for opacity, percentages expressed as decimals, and other normalized values.
unitInterval: Validator<number>Example
const opacity = T.unitInterval.validate(0.5) // Returns 0.5
T.unitInterval.validate(0) // Returns 0 (valid)
T.unitInterval.validate(1) // Returns 1 (valid)
T.unitInterval.validate(1.5) // Throws ValidationError
T.unitInterval.validate(-0.1) // Throws ValidationErrorunknown
Validator that accepts any value without type checking. Useful as a starting point for building custom validations or when you need to accept truly unknown data.
unknown: Validator<unknown>Example
const result = T.unknown.validate(anything) // Returns the value as-is
// result is typed as unknownunknownObject
Validator that ensures a value is an object (non-null, non-array). Does not validate the properties of the object.
unknownObject: Validator<Record<string, unknown>>Example
const obj = T.unknownObject.validate({ any: 'properties' }) // Returns Record<string, unknown>
T.unknownObject.validate(null) // Throws ValidationError: "Expected object, got null"
T.unknownObject.validate([1, 2, 3]) // Throws ValidationError: "Expected object, got an array"Validatable
Interface for objects that can validate unknown values and return typed results. This is the core interface implemented by all validators in the validation system.
interface Validatable<T> {}Example
const customValidator: Validatable<number> = {
validate(value) {
if (typeof value !== 'number') {
throw new ValidationError('Expected number')
}
return value
},
}ValidationError
Error thrown when validation fails. Provides detailed information about what went wrong and where in the data structure the error occurred.
class ValidationError extends Error {}Example
try {
validator.validate(invalidData)
} catch (error) {
if (error instanceof ValidationError) {
console.log(error.message) // "At users.0.email: Expected valid URL"
console.log(error.path) // ['users', 0, 'email']
console.log(error.rawMessage) // "Expected valid URL"
}
}Validator
The main validator class that implements the Validatable interface. This is the base class for all validators and provides methods for validation, type checking, and composing validators.
class Validator<T> implements Validatable<T> {}Example
const numberValidator = new Validator((value) => {
if (typeof value !== 'number') {
throw new ValidationError('Expected number')
}
return value
})
const result = numberValidator.validate(42) // Returns 42 as numberValidatorFn
A function that validates and returns a value of type T from unknown input. The function should throw a ValidationError if the value is invalid.
type ValidatorFn<T> = (value: unknown) => TExample
const stringValidator: ValidatorFn<string> = (value) => {
if (typeof value !== 'string') {
throw new ValidationError('Expected string')
}
return value
}Parameters
| Name | Description |
|---|---|
| The unknown value to validate |
ValidatorUsingKnownGoodVersionFn
A performance-optimized validation function that can use a previously validated value to avoid revalidating unchanged parts of the data structure.
type ValidatorUsingKnownGoodVersionFn<In, Out = In> = (
knownGoodValue: In,
value: unknown
) => OutExample
const optimizedValidator: ValidatorUsingKnownGoodVersionFn<User> = (
knownGood,
newValue
) => {
if (Object.is(knownGood, newValue)) return knownGood
return fullValidation(newValue)
}Parameters
| Name | Description |
|---|---|
| A previously validated value of type In |
| The unknown value to validate |
Methods
arrayOf( )
Creates a validator for arrays where each element is validated using the provided validator.
function arrayOf<T>(itemValidator: Validatable<T>): ArrayOfValidator<T>Example
const numberArray = T.arrayOf(T.number)
numberArray.validate([1, 2, 3]) // Returns number[]
numberArray.validate([1, '2', 3]) // Throws ValidationError at index 1
const userArray = T.arrayOf(T.object({ name: T.string, age: T.number }))Parameters
| Name | Description |
|---|---|
| Validator to use for each array element |
Returns
An ArrayOfValidator that validates both array structure and element types
dict( )
Creates a validator for dictionary objects where both keys and values are validated. Useful for validating objects used as key-value maps.
function dict<Key extends string, Value>(
keyValidator: Validatable<Key>,
valueValidator: Validatable<Value>
): DictValidator<Key, Value>Example
const scores = T.dict(T.string, T.number)
scores.validate({ alice: 100, bob: 85 }) // Valid
const userPrefs = T.dict(
T.string,
T.object({
theme: T.literalEnum('light', 'dark'),
notifications: T.boolean,
})
)Parameters
| Name | Description |
|---|---|
| Validator for object keys |
| Validator for object values |
Returns
DictValidator<Key, Value>A DictValidator that validates all keys and values
jsonDict( )
Creates a validator for JSON dictionaries (objects with string keys and JSON-serializable values).
function jsonDict(): DictValidator<string, JsonValue>Example
const config = T.jsonDict().validate({
setting1: 'value',
setting2: 42,
setting3: ['a', 'b', 'c'],
setting4: { nested: true },
})literal( )
Creates a validator that only accepts a specific literal value.
function literal<T extends boolean | number | string>(
expectedValue: T
): Validator<T>Example
const trueValidator = T.literal(true)
trueValidator.validate(true) // Returns true
trueValidator.validate(false) // Throws ValidationError
const statusValidator = T.literal('active')
statusValidator.validate('active') // Returns "active"
statusValidator.validate('inactive') // Throws ValidationErrorParameters
| Name | Description |
|---|---|
| The exact value that must be matched |
Returns
Validator<T>A validator that only accepts the specified literal value
literalEnum( )
Creates a validator that only accepts one of the provided literal values. This is a convenience function that creates a setEnum from the provided values.
function literalEnum<const Values extends readonly unknown[]>(
...values: Values
): Validator<Values[number]>Example
const themeValidator = T.literalEnum('light', 'dark', 'auto')
themeValidator.validate('light') // Returns 'light'
themeValidator.validate('blue') // Throws ValidationError: Expected "light" or "dark" or "auto", got blueParameters
| Name | Description |
|---|---|
| The allowed literal values |
Returns
Validator<Values[number]>A validator that only accepts the provided literal values
model( )
Creates a validator for named model objects with enhanced error reporting. The model name will be included in error messages to provide better debugging context.
function model<
T extends {
readonly id: string
},
>(name: string, validator: Validatable<T>): Validator<T>Example
const userModel = T.model(
'User',
T.object({
id: T.string,
name: T.string,
email: T.linkUrl,
})
)
// Error message will be: "At User.email: Expected a valid url, got 'invalid-email'"Parameters
| Name | Description |
|---|---|
| The name of the model (used in error messages) |
| The validator for the model structure |
Returns
Validator<T>A Validator with enhanced error reporting that includes the model name
nullable( )
Creates a validator that accepts either the validated type or null.
function nullable<T>(validator: Validatable<T>): Validator<null | T>Example
const nullableString = T.nullable(T.string)
nullableString.validate('hello') // Returns "hello"
nullableString.validate(null) // Returns null
nullableString.validate(undefined) // Throws ValidationErrorParameters
| Name | Description |
|---|---|
| The base validator to make nullable |
Returns
Validator<null | T>A validator that accepts T or null
object( )
Creates a validator for objects with a defined shape. Each property is validated using its corresponding validator from the config object.
function object<Shape extends object>(config: {
readonly [K in keyof Shape]: Validatable<Shape[K]>
}): ObjectValidator<MakeUndefinedOptional<Shape>>Example
const userValidator = T.object({
name: T.string,
age: T.number,
email: T.string.optional(),
isActive: T.boolean,
})
const user = userValidator.validate({
name: 'Alice',
age: 25,
email: 'alice@example.com',
isActive: true,
})
// user is typed with full type safetyParameters
| Name | Description |
|---|---|
| Object mapping property names to their validators |
Returns
ObjectValidator<MakeUndefinedOptional<Shape>>An ObjectValidator that validates the object structure and all properties
optional( )
Creates a validator that accepts either the validated type or undefined.
function optional<T>(validator: Validatable<T>): Validator<T | undefined>Example
const optionalString = T.optional(T.string)
optionalString.validate('hello') // Returns "hello"
optionalString.validate(undefined) // Returns undefined
optionalString.validate(null) // Throws ValidationErrorParameters
| Name | Description |
|---|---|
| The base validator to make optional |
Returns
Validator<T | undefined>A validator that accepts T or undefined
or( )
Creates a validator that accepts values matching either of two validators. Tries the first validator, and if it fails, tries the second validator.
function or<T1, T2>(
v1: Validatable<T1>,
v2: Validatable<T2>
): Validator<T1 | T2>Example
const stringOrNumber = T.or(T.string, T.number)
stringOrNumber.validate('hello') // Returns "hello" as string
stringOrNumber.validate(42) // Returns 42 as number
stringOrNumber.validate(true) // Throws ValidationError from number validatorParameters
| Name | Description |
|---|---|
| The first validator to try |
| The second validator to try if the first fails |
Returns
Validator<T1 | T2>A validator that accepts values matching either validator
setEnum( )
Creates a validator that only accepts values from a given Set of allowed values.
function setEnum<T>(values: ReadonlySet<T>): Validator<T>Example
const allowedColors = new Set(['red', 'green', 'blue'] as const)
const colorValidator = T.setEnum(allowedColors)
colorValidator.validate('red') // Returns 'red'
colorValidator.validate('yellow') // Throws ValidationErrorParameters
| Name | Description |
|---|---|
| Set containing the allowed values |
Returns
Validator<T>A validator that only accepts values from the provided set
union( )
Creates a validator for discriminated union types. Validates objects that can be one of several variants, distinguished by a discriminator property.
function union<
Key extends string,
Config extends UnionValidatorConfig<Key, Config>,
>(key: Key, config: Config): UnionValidator<Key, Config>Example
const shapeValidator = T.union('type', {
circle: T.object({ type: T.literal('circle'), radius: T.number }),
square: T.object({ type: T.literal('square'), size: T.number }),
triangle: T.object({
type: T.literal('triangle'),
base: T.number,
height: T.number,
}),
})
const circle = shapeValidator.validate({ type: 'circle', radius: 5 })
// circle is typed as { type: 'circle'; radius: number }Parameters
| Name | Description |
|---|---|
| The discriminator property name used to determine the variant |
| Object mapping variant names to their validators |
Returns
UnionValidator<Key, Config>A UnionValidator that validates based on the discriminator value