CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ts-interface-checker

Runtime library to validate data against TypeScript interfaces

Pending
Overview
Eval results
Files

type-definition-system.mddocs/

Type Definition System

Comprehensive type definition DSL for creating complex type structures including interfaces, unions, arrays, functions, and enums.

Capabilities

Basic Type Builders

Fundamental type construction functions for creating type definitions.

/**
 * Defines a type name, either built-in or defined in this suite
 * @param value - Type name string
 * @returns TName type node
 */
function name(value: string): TName;

/**
 * Type name implementation with recursive type support
 */
class TName extends TType {
  constructor(public name: string);
  getChecker(suite: ITypeSuite, strict: boolean, allowedProps?: Set<string>): CheckerFunc;
}

/**
 * Defines a literal value type
 * @param value - The literal value
 * @returns TLiteral type node
 */
function lit(value: any): TLiteral;

/**
 * Literal value type implementation
 */
class TLiteral extends TType {
  public name: string; // JSON.stringify(value)
  constructor(public value: any);
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

/**
 * Defines an array type
 * @param typeSpec - Type specification for array elements
 * @returns TArray type node
 */
function array(typeSpec: TypeSpec): TArray;

/**
 * Array type implementation
 */
class TArray extends TType {
  public name?: string; // Generated name like "string[]"
  constructor(public ttype: TType);
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

/**
 * Defines a tuple type with fixed element types
 * @param typeSpec - Type specifications for each tuple position
 * @returns TTuple type node
 */
function tuple(...typeSpec: TypeSpec[]): TTuple;

/**
 * Tuple type implementation with optional rest parameter support
 */
class TTuple extends TType {
  constructor(public ttypes: TType[]);
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

Usage Examples:

import * as t from "ts-interface-checker";

// Basic types by name
const stringType = t.name("string");
const numberType = t.name("number");

// Literal types
const trueLiteral = t.lit(true);
const fooLiteral = t.lit("foo");
const numberLiteral = t.lit(42);

// Array types
const stringArray = t.array("string");
const numberArray = t.array("number");
const objectArray = t.array(t.iface([], { id: "number" }));

// Tuple types
const coordinate = t.tuple("number", "number");
const nameAge = t.tuple("string", "number");
const mixed = t.tuple("string", t.lit(42), "boolean");

Union and Intersection Types

Combine types using union and intersection operations.

/**
 * Defines a union type (one of several types)
 * @param typeSpec - Type specifications for union members
 * @returns TUnion type node
 */
function union(...typeSpec: TypeSpec[]): TUnion;

/**
 * Defines an intersection type (all types simultaneously)
 * @param typeSpec - Type specifications for intersection members
 * @returns TIntersection type node
 */
function intersection(...typeSpec: TypeSpec[]): TIntersection;

/**
 * Union type implementation
 */
class TUnion extends TType {
  constructor(public ttypes: TType[]);
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

/**
 * Intersection type implementation
 */
class TIntersection extends TType {
  constructor(public ttypes: TType[]);
  getChecker(suite: ITypeSuite, strict: boolean, allowedProps?: Set<string>): CheckerFunc;
}

Usage Examples:

// Union types
const stringOrNumber = t.union("string", "number");
const optionalString = t.union("string", "null");
const statusType = t.union(t.lit("pending"), t.lit("complete"), t.lit("error"));

// Complex unions
const idType = t.union("string", "number", t.iface([], { 
  type: t.lit("uuid"), 
  value: "string" 
}));

// Intersection types
const namedObject = t.intersection(
  t.iface([], { name: "string" }),
  t.iface([], { id: "number" })
);

// Mixed intersections
const timestamped = t.intersection(
  "MyInterface",
  t.iface([], { 
    createdAt: "Date",
    updatedAt: "Date" 
  })
);

Interface Types

Define interface types with properties, inheritance, and index signatures.

/**
 * Defines an interface type
 * @param bases - Array of base interface names that this interface extends
 * @param props - Object mapping property names to type specifications
 * @returns TIface type node
 */
function iface(bases: string[], props: {[name: string]: TOptional|TypeSpec}): TIface;

/**
 * Defines an optional property in an interface
 * @param typeSpec - Type specification for the optional property
 * @returns TOptional type node
 */
function opt(typeSpec: TypeSpec): TOptional;

/**
 * Special key for index signatures in interfaces
 */
const indexKey: unique symbol;

/**
 * Optional property wrapper type
 */
class TOptional extends TType {
  constructor(public ttype: TType);
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

/**
 * Interface type implementation
 */
class TIface extends TType {
  public props: TProp[];
  constructor(public bases: string[], props: {[name: string]: TOptional|TypeSpec});
  getChecker(suite: ITypeSuite, strict: boolean, allowedProps?: Set<string>): CheckerFunc;
}

Usage Examples:

// Basic interface
const User = t.iface([], {
  name: "string",
  age: "number",
  email: t.opt("string") // Optional property
});

// Interface with inheritance
const AdminUser = t.iface(["User"], {
  permissions: t.array("string"),
  isActive: "boolean"
});

// Interface with index signature
const Dictionary = t.iface([], {
  [t.indexKey]: "string" // [key: string]: string
});

// Complex interface
const ApiResponse = t.iface([], {
  data: "any",
  status: t.union(t.lit("success"), t.lit("error")),
  message: t.opt("string"),
  timestamp: "Date",
  metadata: t.opt(t.iface([], {
    requestId: "string",
    duration: "number"
  }))
});

Function Types

Define function signatures with parameters and return types.

/**
 * Defines a function type
 * @param resultSpec - Return type specification
 * @param params - Function parameters
 * @returns TFunc type node
 */
function func(resultSpec: TypeSpec, ...params: TParam[]): TFunc;

/**
 * Defines a function parameter
 * @param name - Parameter name
 * @param typeSpec - Parameter type specification
 * @param isOpt - Whether parameter is optional
 * @returns TParam parameter definition
 */
function param(name: string, typeSpec: TypeSpec, isOpt?: boolean): TParam;

/**
 * Defines a rest parameter for tuples
 * @param typeSpec - Type specification for rest elements
 * @returns RestType definition
 */
function rest(typeSpec: TypeSpec): RestType;

/**
 * Function type implementation
 */
class TFunc extends TType {
  constructor(public paramList: TParamList, public result: TType);
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

Usage Examples:

// Basic function
const addFunction = t.func("number",
  t.param("a", "number"),
  t.param("b", "number")
);

// Function with optional parameters
const greetFunction = t.func("string",
  t.param("name", "string"),
  t.param("title", "string", true) // Optional
);

// Function returning complex type
const fetchUser = t.func(
  t.iface([], { name: "string", age: "number" }),
  t.param("id", "string")
);

// Tuple with rest parameters
const flexibleTuple = t.tuple("string", "number", t.rest(t.array("boolean")));

// More complex rest parameter examples
const headersTuple = t.tuple("string", t.rest(t.array("string"))); // ["main", ...headers]
const coordinatesTuple = t.tuple("number", "number", t.rest(t.array("number"))); // [x, y, ...points]

Rest Parameter Types

Special type for handling variable-length tuple elements.

/**
 * Rest parameter type for tuples with variable-length endings
 */
class RestType extends TType {
  constructor(typeSpec: TypeSpec);
  setStart(start: number): void;
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

Usage Examples:

// Rest parameters allow tuples to accept variable numbers of elements
const coordinates = t.tuple("number", "number", t.rest(t.array("number")));

// Valid data:
coordinates.check([10, 20]); // OK - just x, y
coordinates.check([10, 20, 30]); // OK - x, y, z
coordinates.check([10, 20, 30, 40, 50]); // OK - x, y, and additional points

Function Parameter Lists

Container for function parameter definitions and individual parameter representations.

/**
 * Function parameter list type
 */
class TParamList extends TType {
  constructor(public params: TParam[]);
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

/**
 * Function parameter definition
 */
class TParam {
  constructor(public name: string, public ttype: TType, public isOpt: boolean);
}

Usage Examples:

// TParam and TParamList are typically created by func() and param() functions
// but can be accessed when working with TFunc instances

const addFunc = t.func("number",
  t.param("a", "number"),
  t.param("b", "number", true) // Optional parameter
);

// Access parameter information
if (addFunc instanceof TFunc) {
  for (const param of addFunc.paramList.params) {
    console.log(`Parameter: ${param.name}, Type: ${param.ttype}, Optional: ${param.isOpt}`);
    // Output:
    // Parameter: a, Type: [TName object], Optional: false
    // Parameter: b, Type: [TName object], Optional: true
  }
}

// Create parameter list directly
const paramList = new TParamList([
  new TParam("name", t.name("string"), false),
  new TParam("age", t.name("number"), true)
]);

Enum Types

Define enum types with string or numeric values.

/**
 * Defines an enum type
 * @param values - Object mapping enum member names to their values
 * @returns TEnumType type node
 */
function enumtype(values: {[name: string]: string|number}): TEnumType;

/**
 * Defines a literal enum value reference
 * @param name - Enum type name
 * @param prop - Enum member name
 * @returns TEnumLiteral type node
 */
function enumlit(name: string, prop: string): TEnumLiteral;

/**
 * Enum type implementation
 */
class TEnumType extends TType {
  constructor(public values: {[name: string]: string|number});
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

/**
 * Enum literal reference implementation
 */
class TEnumLiteral extends TType {
  constructor(public enumName: string, public prop: string);
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

Usage Examples:

// Numeric enum
const Direction = t.enumtype({
  Up: 1,
  Down: 2,
  Left: 3,
  Right: 4
});

// String enum
const Color = t.enumtype({
  Red: "red",
  Green: "green",
  Blue: "blue"
});

// Mixed enum
const Status = t.enumtype({
  Inactive: 0,
  Active: "active",
  Pending: "pending"
});

// Enum literal references
const upDirection = t.enumlit("Direction", "Up");
const redColor = t.enumlit("Color", "Red");

// Using enum literals in unions
const primaryColors = t.union(
  t.enumlit("Color", "Red"),
  t.enumlit("Color", "Green"),
  t.enumlit("Color", "Blue")
);

Built-in Types

Pre-defined basic types available in the type system.

/**
 * Built-in type suite containing fundamental JavaScript/TypeScript types
 */
const basicTypes: ITypeSuite;

/**
 * Basic type implementation for built-in JavaScript/TypeScript types
 */
class BasicType extends TType {
  constructor(validator: (value: any) => boolean, message: string);
  getChecker(suite: ITypeSuite, strict: boolean): CheckerFunc;
}

The basicTypes suite includes:

  • any, unknown - Universal types
  • number, string, boolean, symbol - Primitive types
  • object, null, undefined, void, never - Object and empty types
  • Date, RegExp - Built-in object types
  • Buffer - Node.js Buffer type (available only in Node.js environments)
  • Typed arrays: Int8Array, Uint8Array, Float32Array, etc.
  • ArrayBuffer - Binary data buffer

Usage Examples:

import { basicTypes } from "ts-interface-checker";

// Basic types are automatically included in createCheckers
// You can also reference them explicitly
const anyType = basicTypes.any;
const dateType = basicTypes.Date;
const bufferType = basicTypes.Buffer; // Available in Node.js

// Using built-in types in definitions
const TimestampedData = t.iface([], {
  data: "any",
  timestamp: "Date",
  buffer: "Buffer" // References built-in Buffer type
});

Interface Property Definitions

Representation of interface properties with their type and optional status.

/**
 * Defines a property in an interface
 */
class TProp {
  constructor(public name: string, public ttype: TType, public isOpt: boolean);
}

Usage Examples:

// TProp instances are typically created internally by the iface() function
// but can be accessed when working with TIface instances

const userInterface = t.iface([], {
  name: "string",
  age: "number",
  email: t.opt("string")
});

// Access properties from a TIface instance
if (userInterface instanceof TIface) {
  for (const prop of userInterface.props) {
    console.log(`Property: ${prop.name}, Optional: ${prop.isOpt}`);
    // Output: 
    // Property: name, Optional: false
    // Property: age, Optional: false  
    // Property: email, Optional: true
  }
}

Type Specification Format

The TypeSpec type allows both TType instances and string references.

/**
 * Type specification - either a TType instance or string name reference
 */
type TypeSpec = TType | string;

Usage Examples:

// Using string references
const userRef = t.iface([], {
  name: "string", // String reference to built-in type
  profile: "UserProfile" // String reference to custom type
});

// Using TType instances
const userDirect = t.iface([], {
  name: t.name("string"), // TType instance
  profile: t.name("UserProfile") // TType instance
});

// Mixed usage (common pattern)
const mixedInterface = t.iface([], {
  id: "number", // String reference
  data: t.union("string", "object"), // TType instance
  optional: t.opt("boolean") // TType instance with opt wrapper
});

Install with Tessl CLI

npx tessl i tessl/npm-ts-interface-checker

docs

checker-creation.md

data-validation.md

error-handling.md

index.md

interface-method-validation.md

type-definition-system.md

tile.json