TypeScript runtime type system for IO decoding/encoding
npx @tessl/cli install tessl/npm-io-ts@2.2.00
# io-ts
1
2
io-ts is a TypeScript runtime type system for IO decoding/encoding that enables runtime validation of data against TypeScript types. It provides a comprehensive API for defining codecs that can validate, decode, and encode data with full type safety and detailed error reporting.
3
4
## Package Information
5
6
- **Package Name**: io-ts
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install io-ts fp-ts`
10
- **Peer Dependencies**: fp-ts (functional programming utilities)
11
12
## Core Imports
13
14
Main stable API:
15
16
```typescript
17
import * as t from "io-ts";
18
// Or specific imports
19
import { Type, string, number, type TypeOf } from "io-ts";
20
```
21
22
Experimental modules (independent APIs):
23
24
```typescript
25
import * as D from "io-ts/Decoder";
26
import * as C from "io-ts/Codec";
27
import * as E from "io-ts/Encoder";
28
```
29
30
CommonJS:
31
32
```javascript
33
const t = require("io-ts");
34
const { PathReporter } = require("io-ts/PathReporter");
35
```
36
37
## Basic Usage
38
39
```typescript
40
import * as t from "io-ts";
41
import { PathReporter } from "io-ts/PathReporter";
42
43
// Define a codec
44
const User = t.type({
45
name: t.string,
46
age: t.number,
47
email: t.string,
48
});
49
50
// Extract the TypeScript type
51
type User = t.TypeOf<typeof User>;
52
53
// Validate data at runtime
54
const data = { name: "Alice", age: 30, email: "alice@example.com" };
55
const result = User.decode(data);
56
57
if (result._tag === "Right") {
58
// Valid data
59
const user: User = result.right;
60
console.log("Valid user:", user);
61
} else {
62
// Invalid data with detailed errors
63
const errors = PathReporter.failure(result.left);
64
console.error("Validation errors:", errors);
65
}
66
```
67
68
## Architecture
69
70
io-ts is built around several key architectural patterns:
71
72
- **Stable API** (index module): Mature, backward-compatible Type system with comprehensive validation
73
- **Experimental APIs**: Modern, composable alternatives (Decoder, Encoder, Codec) with enhanced error handling
74
- **Functional Programming**: Built on fp-ts abstractions with proper category theory implementations
75
- **Runtime Safety**: Bridge between TypeScript's compile-time types and runtime validation
76
- **Composability**: Rich combinator library for building complex types from simple ones
77
- **Error Context**: Detailed validation errors with path information for debugging
78
79
## Capabilities
80
81
### Core Type System
82
83
The foundational Type class and primitive codecs for runtime type validation. This is the main stable API providing comprehensive validation, encoding, and decoding capabilities.
84
85
```typescript { .api }
86
class Type<A, O = A, I = unknown> {
87
constructor(
88
name: string,
89
is: (u: unknown) => u is A,
90
validate: (i: I, context: Context) => Validation<A>,
91
encode: (a: A) => O
92
);
93
decode(i: I): Validation<A>;
94
is(u: unknown): u is A;
95
validate(i: I, context: Context): Validation<A>;
96
encode(a: A): O;
97
}
98
99
type TypeOf<C extends Any> = C["_A"];
100
type InputOf<C extends Any> = C["_I"];
101
type OutputOf<C extends Any> = C["_O"];
102
```
103
104
[Core Type System](./core-types.md)
105
106
### Primitive Codecs
107
108
Built-in codecs for basic JavaScript/TypeScript types with runtime validation.
109
110
```typescript { .api }
111
const string: StringC;
112
const number: NumberC;
113
const boolean: BooleanC;
114
const unknown: UnknownC;
115
const any: AnyC;
116
const never: NeverC;
117
const nullType: NullC;
118
const voidType: VoidC;
119
const UnknownArray: UnknownArrayC;
120
const UnknownRecord: UnknownRecordC;
121
```
122
123
[Primitive Codecs](./primitives.md)
124
125
### Combinators
126
127
Functions for composing complex types from simpler ones, enabling validation of objects, arrays, unions, and more.
128
129
```typescript { .api }
130
function type<P extends Props>(props: P): TypeC<P>;
131
function partial<P extends Props>(props: P): PartialC<P>;
132
function array<C extends Mixed>(item: C): ArrayC<C>;
133
function union<CS extends [Mixed, Mixed, ...Array<Mixed>]>(codecs: CS): UnionC<CS>;
134
function intersection<CS extends [Mixed, Mixed, ...Array<Mixed>]>(codecs: CS): IntersectionC<CS>;
135
function tuple<CS extends [Mixed, ...Array<Mixed>]>(codecs: CS): TupleC<CS>;
136
function record<D extends Mixed, C extends Mixed>(domain: D, codomain: C): RecordC<D, C>;
137
```
138
139
[Combinators](./combinators.md)
140
141
### Refinement & Branding
142
143
Advanced type construction for adding runtime constraints and creating branded types.
144
145
```typescript { .api }
146
function refinement<C extends Any>(
147
codec: C,
148
predicate: Predicate<TypeOf<C>>,
149
name?: string
150
): RefinementC<C>;
151
152
function brand<C extends Any, N extends string, B extends { readonly [K in N]: symbol }>(
153
codec: C,
154
predicate: Refinement<TypeOf<C>, Branded<TypeOf<C>, B>>,
155
name: N
156
): BrandC<C, B>;
157
158
const Int: BrandC<NumberC, IntBrand>;
159
```
160
161
[Refinement & Branding](./refinement.md)
162
163
### Validation & Error Handling
164
165
Comprehensive error reporting system with detailed context information for debugging validation failures.
166
167
```typescript { .api }
168
interface ValidationError {
169
readonly value: unknown;
170
readonly context: Context;
171
readonly message?: string;
172
}
173
174
type Validation<A> = Either<Errors, A>;
175
type Errors = Array<ValidationError>;
176
177
function success<T>(value: T): Validation<T>;
178
function failure<T>(value: unknown, context: Context, message?: string): Validation<T>;
179
```
180
181
[Validation & Error Handling](./validation.md)
182
183
### Modern Decoder API
184
185
Experimental modern decoder system with enhanced error reporting and functional composition patterns.
186
187
```typescript { .api }
188
interface Decoder<I, A> {
189
readonly decode: (i: I) => Either<DecodeError, A>;
190
}
191
192
function fromRefinement<I, A>(refinement: Refinement<I, A>, expected: string): Decoder<I, A>;
193
function struct<A>(properties: { [K in keyof A]: Decoder<unknown, A[K]> }): Decoder<unknown, A>;
194
function array<A>(item: Decoder<unknown, A>): Decoder<unknown, Array<A>>;
195
```
196
197
[Modern Decoder API](./decoder.md)
198
199
### Encoding System
200
201
Experimental encoding system for transforming data between different representations.
202
203
```typescript { .api }
204
interface Encoder<O, A> {
205
readonly encode: (a: A) => O;
206
}
207
208
function struct<P>(encoders: { [K in keyof P]: Encoder<P[K], P[K]> }): Encoder<P, P>;
209
function array<O, A>(item: Encoder<O, A>): Encoder<Array<O>, Array<A>>;
210
```
211
212
[Encoding System](./encoder.md)
213
214
### Codec System
215
216
Experimental unified codec system combining decoding and encoding operations with enhanced composability.
217
218
```typescript { .api }
219
interface Codec<I, O, A> extends Decoder<I, A>, Encoder<O, A> {}
220
221
function make<I, O, A>(decoder: Decoder<I, A>, encoder: Encoder<O, A>): Codec<I, O, A>;
222
function struct<P>(codecs: { [K in keyof P]: Codec<unknown, P[K], P[K]> }): Codec<unknown, P, P>;
223
```
224
225
[Codec System](./codec.md)
226
227
### Schema & Type Classes
228
229
Advanced schema-based type construction and functional programming abstractions for maximum composability.
230
231
```typescript { .api }
232
interface Schema<A> {
233
<S>(S: Schemable<S>): HKT<S, A>;
234
}
235
236
interface Schemable<S> {
237
readonly URI: S;
238
readonly literal: <A extends [Literal, ...Array<Literal>]>(...values: A) => HKT<S, A[number]>;
239
readonly string: HKT<S, string>;
240
readonly number: HKT<S, number>;
241
readonly boolean: HKT<S, boolean>;
242
}
243
```
244
245
[Schema & Type Classes](./schema.md)
246
247
### Error Reporting System
248
249
Error reporting interfaces and implementations for converting validation failures into human-readable messages.
250
251
```typescript { .api }
252
interface Reporter<A> {
253
report: (validation: Validation<any>) => A;
254
}
255
256
const PathReporter: Reporter<Array<string>>;
257
258
function failure(es: Array<ValidationError>): Array<string>;
259
function success(): Array<string>;
260
```
261
262
[Error Reporting System](./reporters.md)
263
264
### Task Decoder API (Experimental)
265
266
**⚠️ EXPERIMENTAL:** Asynchronous decoder system based on TaskEither for validating and decoding data with async operations.
267
268
```typescript { .api }
269
interface TaskDecoder<I, A> extends Kleisli<TaskEither.URI, I, DecodeError, A> {
270
readonly decode: (i: I) => TaskEither<DecodeError, A>;
271
}
272
273
function fromDecoder<I, A>(decoder: Decoder<I, A>): TaskDecoder<I, A>;
274
function struct<A>(properties: { [K in keyof A]: TaskDecoder<unknown, A[K]> }): TaskDecoder<unknown, A>;
275
function parse<A, B>(parser: (a: A) => TaskEither<DecodeError, B>): <I>(from: TaskDecoder<I, A>) => TaskDecoder<I, B>;
276
```
277
278
[Task Decoder API](./task-decoder.md)
279
280
### Infrastructure Modules (Experimental)
281
282
**⚠️ EXPERIMENTAL:** Core infrastructure modules that provide error handling and functional composition utilities.
283
284
```typescript { .api }
285
type DecodeError<E> = Leaf<E> | Key<E> | Index<E> | Member<E> | Lazy<E> | Wrap<E>;
286
type FreeSemigroup<A> = Of<A> | Concat<A>;
287
288
function leaf<E>(actual: unknown, error: E): DecodeError<E>;
289
function key<E>(key: string, kind: Kind, errors: FreeSemigroup<DecodeError<E>>): DecodeError<E>;
290
function of<A>(value: A): FreeSemigroup<A>;
291
function concat<A>(left: FreeSemigroup<A>, right: FreeSemigroup<A>): FreeSemigroup<A>;
292
```
293
294
[Infrastructure Modules](./infrastructure.md)
295
296
## Types
297
298
### Core Types
299
300
```typescript { .api }
301
interface Any extends Type<any, any, any> {}
302
interface Mixed extends Type<any, any, unknown> {}
303
304
interface Props {
305
[key: string]: Mixed;
306
}
307
308
interface AnyProps {
309
[key: string]: Any;
310
}
311
312
interface Context extends ReadonlyArray<ContextEntry> {}
313
314
interface ContextEntry {
315
readonly key: string;
316
readonly type: Decoder<any, any>;
317
readonly actual?: unknown;
318
}
319
```
320
321
### Brand Types
322
323
```typescript { .api }
324
interface Brand<B> {
325
readonly [_brand]: B;
326
}
327
328
type Branded<A, B> = A & Brand<B>;
329
330
interface IntBrand {
331
readonly Int: unique symbol;
332
}
333
334
type Int = Branded<number, IntBrand>;
335
```
336
337
### Validation Types
338
339
```typescript { .api }
340
type Is<A> = (u: unknown) => u is A;
341
type Validate<I, A> = (i: I, context: Context) => Validation<A>;
342
type Decode<I, A> = (i: I) => Validation<A>;
343
type Encode<A, O> = (a: A) => O;
344
```