T

See source code
Table of contents

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 ValidationError

linkUrl

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 ValidationError

nonZeroInteger

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 : never

Example

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 ValidationError

unknown

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 unknown

unknownObject

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 number

ValidatorFn

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) => T

Example

const stringValidator: ValidatorFn<string> = (value) => {
  if (typeof value !== 'string') {
    throw new ValidationError('Expected string')
  }
  return value
}

Parameters

NameDescription

value

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
) => Out

Example

const optimizedValidator: ValidatorUsingKnownGoodVersionFn<User> = (
  knownGood,
  newValue
) => {
  if (Object.is(knownGood, newValue)) return knownGood
  return fullValidation(newValue)
}

Parameters

NameDescription

knownGoodValue

A previously validated value of type In

value

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

NameDescription

itemValidator

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

NameDescription

keyValidator

Validatable<Key>

Validator for object keys

valueValidator

Validatable<Value>

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 ValidationError

Parameters

NameDescription

expectedValue

T

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 blue

Parameters

NameDescription

values

Values

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

NameDescription

name

string

The name of the model (used in error messages)

validator

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 ValidationError

Parameters

NameDescription

validator

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 safety

Parameters

NameDescription

config

{
  readonly [K in keyof Shape]: Validatable<Shape[K]>
}

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 ValidationError

Parameters

NameDescription

validator

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 validator

Parameters

NameDescription

v1

Validatable<T1>

The first validator to try

v2

Validatable<T2>

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 ValidationError

Parameters

NameDescription

values

ReadonlySet<T>

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

NameDescription

key

Key

The discriminator property name used to determine the variant

config

Config

Object mapping variant names to their validators

Returns

UnionValidator<Key, Config>

A UnionValidator that validates based on the discriminator value