Cheat Sheet

A quick reference for ArkType's most common patterns. For full docs, explore the sidebar.

Syntax Kinds

ArkType offers three ways to define the same type. Use whichever fits your context.

import { type } from "arktype"

// string expression — most concise
const  = type("string | number")

// tuple expression — embed non-string operands
const  = type(["string", "|", "number"])

// chained — compose existing types
const  = type("string").or("number")

Keywords

Keywords follow a typescriptType.constraint.subconstraint pattern:

// string keywords
("string.email") // email format
("string.uuid") // UUID format
("string.url") // parsable URL
("string.trim") // morph: trims whitespace
("string.json.parse") // morph: string → parsed JSON
("string.date.parse") // morph: string → Date

// number keywords
("number.integer") // whole numbers
("number.safe") // within safe integer range
("number.epoch") // valid Unix timestamp

Operators

("string | number") // union
("string & /@foo/") // intersection
("number > 0") // exclusive min
("number >= 0") // inclusive min
("string <= 255") // max length

// defaults — valid inside objects (key becomes implicitly optional)
({ email: "string.email = 'n/a'" })

Objects

const  = ({
	name: "string",
	"email?": "string.email", // optional key — use '?' suffix in the key
	age: "number >= 0 = 0" // default value — implicitly optional
})

// index signatures (Record types)
const  = ({
	"[string]": "string" // Record<string, string>
})

// strip undeclared keys
const  = .onUndeclaredKey("delete")

Arrays and Tuples

const  = ("string[]") // string expression
const  = type.number.array() // chained

// tuples — fixed length and positional types
const  = (["string", "number"])

// GOTCHA: type([X]) is a 1-element tuple, NOT an array
const  = ({ id: "string" })
const  = ([]) // tuple of exactly [Item]
const  = .array() // Item[]

// readonly
const  = ("string[]").readonly() // readonly string[]

Composition

const  = ({
	platform: "'android' | 'ios'",
	"version?": "string"
})

// reference in another type — just pass it directly
const  = ({
	name: "string",
	device: 
})

// fluent composition
const  = .and({ role: "'admin'" })
const  = ({ name: "string" }).or({ token: "string" })

Morphs and Pipes

// .to() — validated input → validated output
const  = ("string").to("number.integer")

// .pipe() — validated input → transform function
const  = ("string").pipe(s => s.toUpperCase())

// built-in parse morphs
const  = ("string.date.parse") // string → Date
const  = ("string.json.parse") // string → object
const  = ("string.trim") // string → trimmed string

Type Inference

const  = ({
	name: "string",
	"age?": "number"
})

// extract the TypeScript type
type  = typeof .infer
// { name: string; age?: number }

Error Handling

const  = ({
	name: "string",
	"age?": "number"
})

const  = User({ name: "Alan", age: "not a number" })

if ( instanceof type.errors) {
	// ArkErrors — array-like with .summary
	console.error(.summary)
} else {
	// out is typed as { name: string; age?: number }
	console.log(.name)
}

Common Gotchas

MistakeFix
name: "string | undefined" for optionalUse "name?": "string" — append ? to the key
type([Schema]) for arraysUse Schema.array() — brackets create tuples
"Record<string, T>" with T a variableUse type.Record("string", T) or { "[string]": T }
Manually re-validating after type()Trust ArkType's output — it already validated the structure
type User = typeof Schema.tUse typeof Schema.infer for the output type

On this page