# 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.

```ts
import { type } from "arktype"

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

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

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

## Keywords

Keywords follow a `typescriptType.constraint.subconstraint` pattern:

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

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

## Operators

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

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

## Objects

```ts
const User = type({
	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 Env = type({
	"[string]": "string" // Record<string, string>
})

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

## Arrays and Tuples

```ts
const Strings = type("string[]") // string expression
const Numbers = type.number.array() // chained

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

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

// readonly
const Ids = type("string[]").readonly() // readonly string[]
```

## Composition

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

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

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

## Morphs and Pipes

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

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

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

## Type Inference

```ts
const User = type({
	name: "string",
	"age?": "number"
})

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

## Error Handling

```ts
const User = type({
	name: "string",
	"age?": "number"
})

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

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

## Common Gotchas

| Mistake                                    | Fix                                                         |
| ------------------------------------------ | ----------------------------------------------------------- |
| `name: "string \| undefined"` for optional | Use `"name?": "string"` — append `?` to the **key**         |
| `type([Schema])` for arrays                | Use `Schema.array()` — brackets create tuples               |
| `"Record<string, T>"` with `T` a variable  | Use `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.t`              | Use `typeof Schema.infer` for the output type               |
