or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

concurrency-fibers.mdcontext-services.mddata-structures.mdeffect-core.mderror-observability.mdfunction-utilities.mdindex.mdlayer-system.mdschema-validation.mdstreaming.md
tile.json

schema-validation.mddocs/

Schema Validation

Runtime type validation and transformation system with Schema for parsing, encoding, and validating data with comprehensive error reporting and type safety.

Capabilities

Schema Definition and Operations

interface Schema<in in out A, in in out I = A, out R = never> extends Pipeable {}

declare namespace Schema {
  /**
   * Primitive schemas
   */
  const String: Schema<string>;
  const Number: Schema<number>;
  const Boolean: Schema<boolean>;
  const Date: Schema<Date>;
  
  /**
   * Collection schemas
   */
  function Array<A, I, R>(item: Schema<A, I, R>): Schema<ReadonlyArray<A>, ReadonlyArray<I>, R>;
  function NonEmptyArray<A, I, R>(item: Schema<A, I, R>): Schema<NonEmptyReadonlyArray<A>, NonEmptyReadonlyArray<I>, R>;
  
  /**
   * Object schemas
   */
  function Struct<Fields>(fields: Fields): Schema<{ readonly [K in keyof Fields]: Schema.Type<Fields[K]> }>;
  function Record<K extends PropertyKey, A, I, R>(key: Schema<K>, value: Schema<A, I, R>): Schema<{ readonly [P in K]: A }, { readonly [P in K]: I }, R>;
  
  /**
   * Union and optional schemas
   */
  function Union<Members extends readonly [Schema<any, any, any>, ...Array<Schema<any, any, any>>]>(...members: Members): Schema<Schema.Type<Members[number]>>;
  function Optional<A, I, R>(schema: Schema<A, I, R>): Schema<A | undefined, I | undefined, R>;
  function Nullable<A, I, R>(schema: Schema<A, I, R>): Schema<A | null, I | null, R>;
  
  /**
   * Parsing and validation
   */
  function decode<A, I, R>(schema: Schema<A, I, R>): (u: unknown) => Effect<A, ParseResult.ParseError, R>;
  function encode<A, I, R>(schema: Schema<A, I, R>): (a: A) => Effect<I, ParseResult.ParseError, R>;
  function parse<A, I, R>(schema: Schema<A, I, R>): (u: unknown) => Effect<A, ParseResult.ParseError, R>;
  
  /**
   * Type utilities
   */
  type Type<S> = S extends Schema<infer A, any, any> ? A : never;
  type Encoded<S> = S extends Schema<any, infer I, any> ? I : never;
  type Context<S> = S extends Schema<any, any, infer R> ? R : never;
}

Usage Examples:

import { Schema, Effect, pipe } from "effect";

// Basic schemas
const UserSchema = Schema.Struct({
  id: Schema.Number,
  name: Schema.String,
  email: Schema.String,
  age: Schema.Optional(Schema.Number),
  active: Schema.Boolean
});

type User = Schema.Type<typeof UserSchema>;

// Array schema
const UsersSchema = Schema.Array(UserSchema);

// Validation
const parseUser = Schema.decode(UserSchema);

const result = await Effect.runPromise(
  parseUser({
    id: 1,
    name: "John Doe",
    email: "john@example.com", 
    active: true
  })
);

// Complex validation
const ApiResponseSchema = Schema.Struct({
  success: Schema.Boolean,
  data: Schema.Union(UserSchema, Schema.Array(UserSchema)),
  errors: Schema.Optional(Schema.Array(Schema.String))
});

// Custom transformations
const DateFromString = Schema.transformOrFail(
  Schema.String,
  Schema.Date,
  (s, _, ast) => {
    const date = new Date(s);
    return isNaN(date.getTime()) 
      ? ParseResult.fail(ParseResult.type(ast, s))
      : ParseResult.succeed(date);
  },
  (date) => ParseResult.succeed(date.toISOString())
);

Types

declare namespace ParseResult {
  interface ParseError {
    readonly _tag: "ParseError";
    readonly error: ParseIssue;
  }
  
  interface ParseIssue {
    readonly path: ReadonlyArray<PropertyKey>;
    readonly message: string;
    readonly issues?: ReadonlyArray<ParseIssue>;
  }
}