or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

codec.mdcombinators.mdcore-types.mddecoder.mdencoder.mdindex.mdinfrastructure.mdprimitives.mdrefinement.mdreporters.mdschema.mdtask-decoder.mdvalidation.md
tile.json

tessl/npm-io-ts

TypeScript runtime type system for IO decoding/encoding

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/io-ts@2.2.x

To install, run

npx @tessl/cli install tessl/npm-io-ts@2.2.0

index.mddocs/

io-ts

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.

Package Information

  • Package Name: io-ts
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install io-ts fp-ts
  • Peer Dependencies: fp-ts (functional programming utilities)

Core Imports

Main stable API:

import * as t from "io-ts";
// Or specific imports
import { Type, string, number, type TypeOf } from "io-ts";

Experimental modules (independent APIs):

import * as D from "io-ts/Decoder";
import * as C from "io-ts/Codec";
import * as E from "io-ts/Encoder";

CommonJS:

const t = require("io-ts");
const { PathReporter } = require("io-ts/PathReporter");

Basic Usage

import * as t from "io-ts";
import { PathReporter } from "io-ts/PathReporter";

// Define a codec
const User = t.type({
  name: t.string,
  age: t.number,
  email: t.string,
});

// Extract the TypeScript type
type User = t.TypeOf<typeof User>;

// Validate data at runtime
const data = { name: "Alice", age: 30, email: "alice@example.com" };
const result = User.decode(data);

if (result._tag === "Right") {
  // Valid data
  const user: User = result.right;
  console.log("Valid user:", user);
} else {
  // Invalid data with detailed errors
  const errors = PathReporter.failure(result.left);
  console.error("Validation errors:", errors);
}

Architecture

io-ts is built around several key architectural patterns:

  • Stable API (index module): Mature, backward-compatible Type system with comprehensive validation
  • Experimental APIs: Modern, composable alternatives (Decoder, Encoder, Codec) with enhanced error handling
  • Functional Programming: Built on fp-ts abstractions with proper category theory implementations
  • Runtime Safety: Bridge between TypeScript's compile-time types and runtime validation
  • Composability: Rich combinator library for building complex types from simple ones
  • Error Context: Detailed validation errors with path information for debugging

Capabilities

Core Type System

The foundational Type class and primitive codecs for runtime type validation. This is the main stable API providing comprehensive validation, encoding, and decoding capabilities.

class Type<A, O = A, I = unknown> {
  constructor(
    name: string,
    is: (u: unknown) => u is A,
    validate: (i: I, context: Context) => Validation<A>,
    encode: (a: A) => O
  );
  decode(i: I): Validation<A>;
  is(u: unknown): u is A;
  validate(i: I, context: Context): Validation<A>;
  encode(a: A): O;
}

type TypeOf<C extends Any> = C["_A"];
type InputOf<C extends Any> = C["_I"];
type OutputOf<C extends Any> = C["_O"];

Core Type System

Primitive Codecs

Built-in codecs for basic JavaScript/TypeScript types with runtime validation.

const string: StringC;
const number: NumberC; 
const boolean: BooleanC;
const unknown: UnknownC;
const any: AnyC;
const never: NeverC;
const nullType: NullC;
const voidType: VoidC;
const UnknownArray: UnknownArrayC;
const UnknownRecord: UnknownRecordC;

Primitive Codecs

Combinators

Functions for composing complex types from simpler ones, enabling validation of objects, arrays, unions, and more.

function type<P extends Props>(props: P): TypeC<P>;
function partial<P extends Props>(props: P): PartialC<P>;
function array<C extends Mixed>(item: C): ArrayC<C>;
function union<CS extends [Mixed, Mixed, ...Array<Mixed>]>(codecs: CS): UnionC<CS>;
function intersection<CS extends [Mixed, Mixed, ...Array<Mixed>]>(codecs: CS): IntersectionC<CS>;
function tuple<CS extends [Mixed, ...Array<Mixed>]>(codecs: CS): TupleC<CS>;
function record<D extends Mixed, C extends Mixed>(domain: D, codomain: C): RecordC<D, C>;

Combinators

Refinement & Branding

Advanced type construction for adding runtime constraints and creating branded types.

function refinement<C extends Any>(
  codec: C,
  predicate: Predicate<TypeOf<C>>,
  name?: string
): RefinementC<C>;

function brand<C extends Any, N extends string, B extends { readonly [K in N]: symbol }>(
  codec: C,
  predicate: Refinement<TypeOf<C>, Branded<TypeOf<C>, B>>,
  name: N
): BrandC<C, B>;

const Int: BrandC<NumberC, IntBrand>;

Refinement & Branding

Validation & Error Handling

Comprehensive error reporting system with detailed context information for debugging validation failures.

interface ValidationError {
  readonly value: unknown;
  readonly context: Context;
  readonly message?: string;
}

type Validation<A> = Either<Errors, A>;
type Errors = Array<ValidationError>;

function success<T>(value: T): Validation<T>;
function failure<T>(value: unknown, context: Context, message?: string): Validation<T>;

Validation & Error Handling

Modern Decoder API

Experimental modern decoder system with enhanced error reporting and functional composition patterns.

interface Decoder<I, A> {
  readonly decode: (i: I) => Either<DecodeError, A>;
}

function fromRefinement<I, A>(refinement: Refinement<I, A>, expected: string): Decoder<I, A>;
function struct<A>(properties: { [K in keyof A]: Decoder<unknown, A[K]> }): Decoder<unknown, A>;
function array<A>(item: Decoder<unknown, A>): Decoder<unknown, Array<A>>;

Modern Decoder API

Encoding System

Experimental encoding system for transforming data between different representations.

interface Encoder<O, A> {
  readonly encode: (a: A) => O;
}

function struct<P>(encoders: { [K in keyof P]: Encoder<P[K], P[K]> }): Encoder<P, P>;
function array<O, A>(item: Encoder<O, A>): Encoder<Array<O>, Array<A>>;

Encoding System

Codec System

Experimental unified codec system combining decoding and encoding operations with enhanced composability.

interface Codec<I, O, A> extends Decoder<I, A>, Encoder<O, A> {}

function make<I, O, A>(decoder: Decoder<I, A>, encoder: Encoder<O, A>): Codec<I, O, A>;
function struct<P>(codecs: { [K in keyof P]: Codec<unknown, P[K], P[K]> }): Codec<unknown, P, P>;

Codec System

Schema & Type Classes

Advanced schema-based type construction and functional programming abstractions for maximum composability.

interface Schema<A> {
  <S>(S: Schemable<S>): HKT<S, A>;
}

interface Schemable<S> {
  readonly URI: S;
  readonly literal: <A extends [Literal, ...Array<Literal>]>(...values: A) => HKT<S, A[number]>;
  readonly string: HKT<S, string>;
  readonly number: HKT<S, number>;
  readonly boolean: HKT<S, boolean>;
}

Schema & Type Classes

Error Reporting System

Error reporting interfaces and implementations for converting validation failures into human-readable messages.

interface Reporter<A> {
  report: (validation: Validation<any>) => A;
}

const PathReporter: Reporter<Array<string>>;

function failure(es: Array<ValidationError>): Array<string>;
function success(): Array<string>;

Error Reporting System

Task Decoder API (Experimental)

⚠️ EXPERIMENTAL: Asynchronous decoder system based on TaskEither for validating and decoding data with async operations.

interface TaskDecoder<I, A> extends Kleisli<TaskEither.URI, I, DecodeError, A> {
  readonly decode: (i: I) => TaskEither<DecodeError, A>;
}

function fromDecoder<I, A>(decoder: Decoder<I, A>): TaskDecoder<I, A>;
function struct<A>(properties: { [K in keyof A]: TaskDecoder<unknown, A[K]> }): TaskDecoder<unknown, A>;
function parse<A, B>(parser: (a: A) => TaskEither<DecodeError, B>): <I>(from: TaskDecoder<I, A>) => TaskDecoder<I, B>;

Task Decoder API

Infrastructure Modules (Experimental)

⚠️ EXPERIMENTAL: Core infrastructure modules that provide error handling and functional composition utilities.

type DecodeError<E> = Leaf<E> | Key<E> | Index<E> | Member<E> | Lazy<E> | Wrap<E>;
type FreeSemigroup<A> = Of<A> | Concat<A>;

function leaf<E>(actual: unknown, error: E): DecodeError<E>;
function key<E>(key: string, kind: Kind, errors: FreeSemigroup<DecodeError<E>>): DecodeError<E>;
function of<A>(value: A): FreeSemigroup<A>;
function concat<A>(left: FreeSemigroup<A>, right: FreeSemigroup<A>): FreeSemigroup<A>;

Infrastructure Modules

Types

Core Types

interface Any extends Type<any, any, any> {}
interface Mixed extends Type<any, any, unknown> {}

interface Props {
  [key: string]: Mixed;
}

interface AnyProps {
  [key: string]: Any;  
}

interface Context extends ReadonlyArray<ContextEntry> {}

interface ContextEntry {
  readonly key: string;
  readonly type: Decoder<any, any>;
  readonly actual?: unknown;
}

Brand Types

interface Brand<B> {
  readonly [_brand]: B;
}

type Branded<A, B> = A & Brand<B>;

interface IntBrand {
  readonly Int: unique symbol;
}

type Int = Branded<number, IntBrand>;

Validation Types

type Is<A> = (u: unknown) => u is A;
type Validate<I, A> = (i: I, context: Context) => Validation<A>;
type Decode<I, A> = (i: I) => Validation<A>;
type Encode<A, O> = (a: A) => O;