Decompose monolithic readme into docs/ directory structure

This commit is contained in:
2026-04-23 13:57:56 +00:00
parent 560bb00433
commit f8b2cdd5a4
47 changed files with 1936 additions and 1829 deletions

42
docs/types/conditional.md Normal file
View File

@@ -0,0 +1,42 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Conditional Types
TypeBox supports runtime conditional types with the Extends function. This function performs a structural assignability check against the first (`left`) and second (`right`) arguments and will return either the third (`true`) or fourth (`false`) argument based on the result. The conditional types Exclude and Extract are also supported. The following shows both TypeScript and TypeBox examples of conditional types.
```typescript
// Extends
const A = Type.Extends(
// type A = string extends number ? 1 : 2
Type.String(), //
Type.Number(), // ... evaluated as
Type.Literal(1), //
Type.Literal(2) // const A: TLiteral<2>
);
// Extract
const B = Type.Extract(
// type B = Extract<1 | 2 | 3, 1>
Type.Union([
//
Type.Literal(1), // ... evaluated as
Type.Literal(2), //
Type.Literal(3), // const B: TLiteral<1>
]),
Type.Literal(1)
);
// Exclude
const C = Type.Exclude(
// type C = Exclude<1 | 2 | 3, 1>
Type.Union([
//
Type.Literal(1), // ... evaluated as
Type.Literal(2), //
Type.Literal(3), // const C: TUnion<[
]), // TLiteral<2>,
Type.Literal(1) // TLiteral<3>,
); // ]>
```
Back to [Home](../../readme.md)

16
docs/types/generics.md Normal file
View File

@@ -0,0 +1,16 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Generic Types
Generic types can be created with generic functions.
```typescript
const Nullable = <T extends TSchema>(T: T) => {
// type Nullable<T> = T | null
return Type.Union([T, Type.Null()]);
};
const T = Nullable(Type.String()); // type T = Nullable<string>
```
Back to [Home](../../readme.md)

41
docs/types/indexed.md Normal file
View File

@@ -0,0 +1,41 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Indexed Access Types
TypeBox supports indexed access types with the Index function. This function enables uniform access to interior property and element types without having to extract them from the underlying schema representation. Index types are supported for Object, Array, Tuple, Union and Intersect types.
```typescript
const T = Type.Object({
// type T = {
x: Type.Number(), // x: number,
y: Type.String(), // y: string,
z: Type.Boolean(), // z: boolean
}); // }
const A = Type.Index(T, ["x"]); // type A = T['x']
//
// ... evaluated as
//
// const A: TNumber
const B = Type.Index(T, ["x", "y"]); // type B = T['x' | 'y']
//
// ... evaluated as
//
// const B: TUnion<[
// TNumber,
// TString,
// ]>
const C = Type.Index(T, Type.KeyOf(T)); // type C = T[keyof T]
//
// ... evaluated as
//
// const C: TUnion<[
// TNumber,
// TString,
// TBoolean
// ]>
```
Back to [Home](../../readme.md)

101
docs/types/javascript.md Normal file
View File

@@ -0,0 +1,101 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# JavaScript Types
TypeBox provides an extended type set that can be used to create schematics for common JavaScript constructs. These types can not be used with any standard Json Schema validator; but can be used to frame schematics for interfaces that may receive Json validated data. JavaScript types are prefixed with the `[JavaScript]` JSDoc comment for convenience. The following table lists the supported types.
```typescript
TypeBox TypeScript Extended Schema
const T = Type.Constructor([ type T = new ( const T = {
Type.String(), arg0: string, type: 'Constructor',
Type.Number() arg0: number parameters: [{
], Type.Boolean()) ) => boolean type: 'string'
}, {
type: 'number'
}],
returns: {
type: 'boolean'
}
}
const T = Type.Function([ type T = ( const T = {
| Type.String(), arg0: string, type: 'Function',
Type.Number() arg1: number parameters: [{
], Type.Boolean()) ) => boolean type: 'string'
}, {
type: 'number'
}],
returns: {
type: 'boolean'
}
}
const T = Type.Promise( type T = Promise<string> const T = {
Type.String() type: 'Promise',
) item: {
type: 'string'
}
}
const T = type T = const T = {
Type.AsyncIterator( AsyncIterableIterator< type: 'AsyncIterator',
Type.String() string items: {
) > type: 'string'
}
}
const T = Type.Iterator( type T = const T = {
Type.String() IterableIterator<string> type: 'Iterator',
) items: {
type: 'string'
}
}
const T = Type.RegExp(/abc/i) type T = string const T = {
type: 'RegExp'
source: 'abc'
flags: 'i'
}
const T = Type.Uint8Array() type T = Uint8Array const T = {
type: 'Uint8Array'
}
const T = Type.Date() type T = Date const T = {
type: 'Date'
}
const T = Type.Undefined() type T = undefined const T = {
type: 'undefined'
}
const T = Type.Symbol() type T = symbol const T = {
type: 'symbol'
}
const T = Type.BigInt() type T = bigint const T = {
type: 'bigint'
}
const T = Type.Void() type T = void const T = {
type: 'void'
}
```
Back to [Home](../../readme.md)

342
docs/types/json.md Normal file
View File

@@ -0,0 +1,342 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Json Types
TypeBox types are Json Schema fragments that compose into more complex types. Each fragment is structured such that any Json Schema compliant validator can runtime assert a value the same way TypeScript will statically assert a type. TypeBox offers a set of Json Types which are used to create Json Schema compliant schematics as well as a JavaScript type set used to create schematics for constructs native to JavaScript.
The following table lists the supported Json types. These types are fully compatible with the Json Schema Draft 7 specification.
```typescript
TypeBox TypeScript Json Schema
const T = Type.Any() type T = any const T = { }
const T = Type.Unknown() type T = unknown const T = { }
const T = Type.String() type T = string const T = {
type: 'string'
}
const T = Type.Number() type T = number const T = {
type: 'number'
}
const T = Type.Integer() type T = number const T = {
type: 'integer'
}
const T = Type.Boolean() type T = boolean const T = {
type: 'boolean'
}
const T = Type.Null() type T = null const T = {
type: 'null'
}
const T = Type.Literal(42) type T = 42 const T = {
const: 42,
type: 'number'
}
const T = Type.Array( type T = number[] const T = {
Type.Number() type: 'array',
) items: {
type: 'number'
}
}
const T = Type.Object({ type T = { const T = {
x: Type.Number(), x: number, type: 'object',
y: Type.Number() y: number required: ['x', 'y'],
}) } properties: {
x: {
type: 'number'
},
y: {
type: 'number'
}
}
}
const T = Type.Tuple([ type T = [number, number] const T = {
Type.Number(), type: 'array',
Type.Number() items: [{
]) type: 'number'
}, {
type: 'number'
}],
additionalItems: false,
minItems: 2,
maxItems: 2
}
enum Foo { enum Foo { const T = {
A, A, anyOf: [{
B B type: 'number',
} } const: 0
}, {
const T = Type.Enum(Foo) type T = Foo type: 'number',
const: 1
}]
}
const T = Type.Const({ type T = { const T = {
x: 1, readonly x: 1, type: 'object',
y: 2, readonly y: 2 required: ['x', 'y'],
} as const) } properties: {
x: {
type: 'number',
const: 1
},
y: {
type: 'number',
const: 2
}
}
}
const T = Type.KeyOf( type T = keyof { const T = {
Type.Object({ x: number, anyOf: [{
x: Type.Number(), y: number type: 'string',
y: Type.Number() } const: 'x'
}) }, {
) type: 'string',
const: 'y'
}]
}
const T = Type.Union([ type T = string | number const T = {
Type.String(), anyOf: [{
Type.Number() type: 'string'
]) }, {
type: 'number'
}]
}
const T = Type.Intersect([ type T = { const T = {
Type.Object({ x: number allOf: [{
x: Type.Number() } & { type: 'object',
}), y: number required: ['x'],
Type.Object({ } properties: {
y: Type.Number() x: {
}) type: 'number'
]) }
}
}, {
type: 'object', |
required: ['y'],
properties: {
y: {
type: 'number'
}
}
}]
}
const T = Type.Composite([ type T = { const T = {
Type.Object({ x: number, type: 'object',
x: Type.Number() y: number required: ['x', 'y'],
}), } properties: {
Type.Object({ x: {
y: Type.Number() type: 'number'
}) },
]) y: {
type: 'number'
}
}
}
const T = Type.Never() type T = never const T = {
not: {}
}
const T = Type.Not( | type T = unknown const T = {
Type.String() not: {
) type: 'string'
}
}
const T = Type.Extends( type T = const T = {
Type.String(), string extends number const: false,
Type.Number(), ? true type: 'boolean'
Type.Literal(true), : false }
Type.Literal(false)
)
const T = Type.Extract( type T = Extract< const T = {
Type.Union([ string | number, type: 'string'
Type.String(), string }
Type.Number(), >
]),
Type.String()
)
const T = Type.Exclude( type T = Exclude< const T = {
Type.Union([ string | number, type: 'number'
Type.String(), string }
Type.Number(), >
]),
Type.String()
)
const T = Type.Mapped( type T = { const T = {
Type.Union([ [_ in 'x' | 'y'] : number type: 'object',
Type.Literal('x'), } required: ['x', 'y'],
Type.Literal('y') properties: {
]), x: {
() => Type.Number() type: 'number'
) },
y: {
type: 'number'
}
}
}
const U = Type.Union([ type U = 'open' | 'close' const T = {
Type.Literal('open'), type: 'string',
Type.Literal('close') type T = `on${U}` pattern: '^on(open|close)$'
]) }
const T = Type
.TemplateLiteral([
Type.Literal('on'),
U
])
const T = Type.Record( type T = Record< const T = {
Type.String(), string, type: 'object',
Type.Number() number patternProperties: {
) > '^.*$': {
type: 'number'
}
}
}
const T = Type.Partial( type T = Partial<{ const T = {
Type.Object({ x: number, type: 'object',
x: Type.Number(), y: number properties: {
y: Type.Number() | }> x: {
}) type: 'number'
) },
y: {
type: 'number'
}
}
}
const T = Type.Required( type T = Required<{ const T = {
Type.Object({ x?: number, type: 'object',
x: Type.Optional( y?: number required: ['x', 'y'],
Type.Number() | }> properties: {
), x: {
y: Type.Optional( type: 'number'
Type.Number() },
) y: {
}) type: 'number'
) }
}
}
const T = Type.Pick( type T = Pick<{ const T = {
Type.Object({ x: number, type: 'object',
x: Type.Number(), y: number required: ['x'],
y: Type.Number() }, 'x'> properties: {
}), ['x'] | x: {
) type: 'number'
}
}
}
const T = Type.Omit( type T = Omit<{ const T = {
Type.Object({ x: number, type: 'object',
x: Type.Number(), y: number required: ['y'],
y: Type.Number() }, 'x'> properties: {
}), ['x'] | y: {
) type: 'number'
}
}
}
const T = Type.Index( type T = { const T = {
Type.Object({ x: number, type: 'number'
x: Type.Number(), y: string }
y: Type.String() }['x']
}), ['x']
)
const A = Type.Tuple([ type A = [0, 1] const T = {
Type.Literal(0), type B = [2, 3] type: 'array',
Type.Literal(1) type T = [ items: [
]) ...A, { const: 0 },
const B = Type.Tuple([ ...B { const: 1 },
| Type.Literal(2), ] { const: 2 },
| Type.Literal(3) { const: 3 }
]) ],
const T = Type.Tuple([ additionalItems: false,
| ...Type.Rest(A), minItems: 4,
| ...Type.Rest(B) maxItems: 4
]) }
const T = Type.Uncapitalize( type T = Uncapitalize< const T = {
Type.Literal('Hello') 'Hello' type: 'string',
) > const: 'hello'
}
const T = Type.Capitalize( type T = Capitalize< const T = {
Type.Literal('hello') 'hello' type: 'string',
) > const: 'Hello'
}
const T = Type.Uppercase( type T = Uppercase< const T = {
Type.Literal('hello') 'hello' type: 'string',
) > const: 'HELLO'
}
const T = Type.Lowercase( type T = Lowercase< const T = {
Type.Literal('HELLO') 'HELLO' type: 'string',
) > const: 'hello'
}
const R = Type.Ref('T') type R = unknown const R = { $ref: 'T' }
```
Back to [Home](../../readme.md)

27
docs/types/mapped.md Normal file
View File

@@ -0,0 +1,27 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Mapped Types
TypeBox supports mapped types with the Mapped function. This function accepts two arguments, the first is a union type typically derived from KeyOf, the second is a mapping function that receives a mapping key `K` that can be used to index properties of a type. The following implements a mapped type that remaps each property to be `T | null`.
```typescript
const T = Type.Object({
// type T = {
x: Type.Number(), // x: number,
y: Type.String(), // y: string,
z: Type.Boolean(), // z: boolean
}); // }
const M = Type.Mapped(Type.KeyOf(T), (K) => {
// type M = { [K in keyof T]: T[K] | null }
return Type.Union([Type.Index(T, K), Type.Null()]); //
}); // ... evaluated as
//
// const M: TObject<{
// x: TUnion<[TNumber, TNull]>,
// y: TUnion<[TString, TNull]>,
// z: TUnion<[TBoolean, TNull]>
// }>
```
Back to [Home](../../readme.md)

35
docs/types/modules.md Normal file
View File

@@ -0,0 +1,35 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Module Types
Module types are containers for a set of referential types. Modules act as namespaces, enabling types to reference one another via string identifiers. Modules support both singular and mutually recursive references, as well as deferred dereferencing for computed types such as Partial. Types imported from a module are expressed using the Json Schema `$defs` keyword.
```typescript
const Module = Type.Module({
PartialUser: Type.Partial(Type.Ref("User")), // TComputed<'Partial', [TRef<'User'>]>
User: Type.Object({
// TObject<{
id: Type.String(), // user: TString,
name: Type.String(), // name: TString,
email: Type.String(), // email: TString
}), // }>
});
const User = Module.Import("User"); // const User: TImport<{...}, 'User'>
type User = Static<typeof User>; // type User = {
// id: string,
// name: string,
// email: string
// }
const PartialUser = Module.Import("PartialUser"); // const PartialUser: TImport<{...}, 'PartialUser'>
type PartialUser = Static<typeof PartialUser>; // type PartialUser = {
// id?: string,
// name?: string,
// email?: string
// }
```
Back to [Home](../../readme.md)

33
docs/types/options.md Normal file
View File

@@ -0,0 +1,33 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Options
You can pass Json Schema options on the last argument of any given type. Option hints specific to each type are provided for convenience.
```typescript
// String must be an email
const T = Type.String({
// const T = {
format: "email", // type: 'string',
}); // format: 'email'
// }
// Number must be a multiple of 2
const T = Type.Number({
// const T = {
multipleOf: 2, // type: 'number',
}); // multipleOf: 2
// }
// Array must have at least 5 integer values
const T = Type.Array(Type.Integer(), {
// const T = {
minItems: 5, // type: 'array',
}); // minItems: 5,
// items: {
// type: 'integer'
// }
// }
```
Back to [Home](../../readme.md)

45
docs/types/properties.md Normal file
View File

@@ -0,0 +1,45 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Properties
Object properties can be modified with Readonly and Optional. The following table shows how these modifiers map between TypeScript and Json Schema.
```typescript
TypeBox TypeScript Json Schema
const T = Type.Object({ type T = { const T = {
name: Type.ReadonlyOptional( readonly name?: string type: 'object',
Type.String() } properties: {
) name: {
}) type: 'string'
}
}
}
const T = Type.Object({ type T = { const T = {
name: Type.Readonly( readonly name: string type: 'object',
Type.String() } properties: {
) name: {
}) type: 'string'
}
},
required: ['name']
}
const T = Type.Object({ type T = { const T = {
name: Type.Optional( name?: string type: 'object',
Type.String() } properties: {
) name: {
}) type: 'string'
}
}
}
```
Back to [Home](../../readme.md)

43
docs/types/recursive.md Normal file
View File

@@ -0,0 +1,43 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Recursive Types
Use the Recursive function to create recursive types.
```typescript
const Node = Type.Recursive(
(This) =>
Type.Object({
// const Node = {
id: Type.String(), // $id: 'Node',
nodes: Type.Array(This), // type: 'object',
}),
{ $id: "Node" }
); // properties: {
// id: {
// type: 'string'
// },
// nodes: {
// type: 'array',
// items: {
// $ref: 'Node'
// }
// }
// },
// required: [
// 'id',
// 'nodes'
// ]
// }
type Node = Static<typeof Node>; // type Node = {
// id: string
// nodes: Node[]
// }
function test(node: Node) {
const id = node.nodes[0].nodes[0].id; // id is string
}
```
Back to [Home](../../readme.md)

View File

@@ -0,0 +1,36 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Template Literal Types
TypeBox supports template literal types with the TemplateLiteral function. This type can be created using a syntax similar to the TypeScript template literal syntax or composed from exterior types. TypeBox encodes template literals as regular expressions which enables the template to be checked by Json Schema validators. This type also supports regular expression parsing that enables template patterns to be used for generative types. The following shows both TypeScript and TypeBox usage.
```typescript
// TypeScript
type K = `prop${"A" | "B" | "C"}`; // type T = 'propA' | 'propB' | 'propC'
type R = Record<K, string>; // type R = {
// propA: string
// propB: string
// propC: string
// }
// TypeBox
const K = Type.TemplateLiteral("prop${A|B|C}"); // const K: TTemplateLiteral<[
// TLiteral<'prop'>,
// TUnion<[
// TLiteral<'A'>,
// TLiteral<'B'>,
// TLiteral<'C'>,
// ]>
// ]>
const R = Type.Record(K, Type.String()); // const R: TObject<{
// propA: TString,
// propB: TString,
// propC: TString,
// }>
```
Back to [Home](../../readme.md)

32
docs/types/transform.md Normal file
View File

@@ -0,0 +1,32 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Transform Types
TypeBox supports value decoding and encoding with Transform types. These types work in tandem with the Encode and Decode functions available on the Value and TypeCompiler submodules. Transform types can be used to convert Json encoded values into constructs more natural to JavaScript. The following creates a Transform type to decode numbers into Dates using the Value submodule.
```typescript
import { Value } from "@alkdev/typebox/value";
const T = Type.Transform(Type.Number())
.Decode((value) => new Date(value)) // decode: number to Date
.Encode((value) => value.getTime()); // encode: Date to number
const D = Value.Decode(T, 0); // const D = Date(1970-01-01T00:00:00.000Z)
const E = Value.Encode(T, D); // const E = 0
```
Use the StaticEncode or StaticDecode types to infer a Transform type.
```typescript
import { Static, StaticDecode, StaticEncode } from "@alkdev/typebox";
const T = Type.Transform(Type.Array(Type.Number(), { uniqueItems: true }))
.Decode((value) => new Set(value))
.Encode((value) => [...value]);
type D = StaticDecode<typeof T>; // type D = Set<number>
type E = StaticEncode<typeof T>; // type E = Array<number>
type T = Static<typeof T>; // type T = Array<number>
```
Back to [Home](../../readme.md)

17
docs/types/typeguard.md Normal file
View File

@@ -0,0 +1,17 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# TypeGuard
TypeBox can check its own types with the TypeGuard module. This module is written for type introspection and provides structural tests for every built-in TypeBox type. Functions of this module return `is` guards which can be used with control flow assertions to obtain schema inference for unknown values. The following guards that the value `T` is TString.
```typescript
import { TypeGuard, Kind } from "@alkdev/typebox";
const T = { [Kind]: "String", type: "string" };
if (TypeGuard.IsString(T)) {
// T is TString
}
```
Back to [Home](../../readme.md)

41
docs/types/unsafe.md Normal file
View File

@@ -0,0 +1,41 @@
[Overview](../overview.md) | [Installation](../installation.md) | [Usage](../usage.md) | **Types** | [Values](../values/) | [Syntax](../syntax/) | [TypeRegistry](../type-registry.md) | [TypeCheck](../type-check.md)
# Unsafe Types
TypeBox supports user defined types with Unsafe. This type allows you to specify both schema representation and inference type. The following creates an Unsafe type with a number schema that infers as string.
```typescript
const T = Type.Unsafe<string>({ type: "number" }); // const T = { type: 'number' }
type T = Static<typeof T>; // type T = string - ?
```
The Unsafe type is often used to create schematics for extended specifications like OpenAPI.
```typescript
const Nullable = <T extends TSchema>(schema: T) =>
Type.Unsafe<Static<T> | null>({
...schema,
nullable: true,
});
const T = Nullable(Type.String()); // const T = {
// type: 'string',
// nullable: true
// }
type T = Static<typeof T>; // type T = string | null
const StringEnum = <T extends string[]>(values: [...T]) =>
Type.Unsafe<T[number]>({
type: "string",
enum: values,
});
const S = StringEnum(["A", "B", "C"]); // const S = {
// enum: ['A', 'B', 'C']
// }
type S = Static<typeof T>; // type S = 'A' | 'B' | 'C'
```
Back to [Home](../../readme.md)