CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-ts-json-schema-generator

Generate JSON schema from your TypeScript sources with extensive customization options

Pending
Overview
Eval results
Files

type-formatting.mddocs/

Type Formatting

Convert internal type representations to JSON schema definitions with customizable formatters for precise control over schema output format.

Capabilities

Formatter Factory Function

Creates a comprehensive type formatter with all built-in formatters and optional custom extensions.

/**
 * Create a type formatter with all built-in formatters
 * @param config - Configuration object
 * @param augmentor - Optional function to add custom formatters
 * @returns Configured TypeFormatter instance
 */
function createFormatter(
  config: CompletedConfig, 
  augmentor?: FormatterAugmentor
): TypeFormatter;

type FormatterAugmentor = (
  formatter: MutableTypeFormatter,
  circularReferenceTypeFormatter: CircularReferenceTypeFormatter
) => void;

Usage Examples:

import { createFormatter, SubTypeFormatter, Definition } from "ts-json-schema-generator";

// Basic formatter creation
const formatter = createFormatter(config);

// Formatter with custom extension
const customFormatter = createFormatter(config, (fmt, circularRef) => {
  fmt.addTypeFormatter(new MyCustomFormatter(circularRef));
});

Core Formatter Interface

Primary interface for converting internal types to JSON schema definitions.

interface TypeFormatter {
  /**
   * Generate JSON schema definition for a type
   * @param type - Internal type representation
   * @returns JSON schema definition object
   */
  getDefinition(type: BaseType): Definition;
  
  /**
   * Get child types that need definitions
   * @param type - Internal type representation  
   * @returns Array of child types
   */
  getChildren(type: BaseType): BaseType[];
}

Extensible Formatter System

Custom formatter interface for handling special types or generating custom schema formats.

interface SubTypeFormatter extends TypeFormatter {
  /**
   * Check if this formatter can handle the given type
   * @param type - Internal type representation to check
   * @returns true if this formatter supports the type
   */
  supportsType(type: BaseType): boolean;
}

interface MutableTypeFormatter {
  /**
   * Add a custom formatter to the formatting chain
   * @param formatter - Custom formatter implementation
   */
  addTypeFormatter(formatter: SubTypeFormatter): void;
}

Custom Formatter Example:

import { SubTypeFormatter, BaseType, Definition, FunctionType } from "ts-json-schema-generator";

class MyFunctionFormatter implements SubTypeFormatter {
  constructor(private childTypeFormatter: TypeFormatter) {}
  
  supportsType(type: BaseType): boolean {
    return type instanceof FunctionType;
  }
  
  getDefinition(type: FunctionType): Definition {
    return {
      type: "object",
      properties: {
        isFunction: { type: "boolean", const: true }
      }
    };
  }
  
  getChildren(type: FunctionType): BaseType[] {
    return []; // or return child types if needed
  }
}

Built-in Type Formatters

Comprehensive set of formatters for all internal type representations.

Primitive Type Formatters

/** Format string types */
class StringTypeFormatter implements SubTypeFormatter {}

/** Format number types */
class NumberTypeFormatter implements SubTypeFormatter {}

/** Format boolean types */
class BooleanTypeFormatter implements SubTypeFormatter {}

/** Format any types */
class AnyTypeFormatter implements SubTypeFormatter {}

/** Format unknown types */
class UnknownTypeFormatter implements SubTypeFormatter {}

/** Format void types */
class VoidTypeFormatter implements SubTypeFormatter {}

/** Format never types */
class NeverTypeFormatter implements SubTypeFormatter {}

/** Format undefined types */
class UndefinedTypeFormatter implements SubTypeFormatter {}

/** Format null types */
class NullTypeFormatter implements SubTypeFormatter {}

/** Format symbol types */
class SymbolTypeFormatter implements SubTypeFormatter {}

Complex Type Formatters

/** Format object types with properties */
class ObjectTypeFormatter implements SubTypeFormatter {}

/** Format array types */
class ArrayTypeFormatter implements SubTypeFormatter {}

/** Format tuple types */
class TupleTypeFormatter implements SubTypeFormatter {}

/** Format union types */
class UnionTypeFormatter implements SubTypeFormatter {}

/** Format intersection types */
class IntersectionTypeFormatter implements SubTypeFormatter {}

/** Format enum types */
class EnumTypeFormatter implements SubTypeFormatter {}

/** Format literal types */
class LiteralTypeFormatter implements SubTypeFormatter {}

/** Format literal union types */
class LiteralUnionTypeFormatter implements SubTypeFormatter {}

Special Type Formatters

/** Format type aliases */
class AliasTypeFormatter implements SubTypeFormatter {}

/** Format annotated types with JSDoc metadata */
class AnnotatedTypeFormatter implements SubTypeFormatter {}

/** Format definition references */
class DefinitionTypeFormatter implements SubTypeFormatter {}

/** Format reference types */
class ReferenceTypeFormatter implements SubTypeFormatter {}

/** Format optional types */
class OptionalTypeFormatter implements SubTypeFormatter {}

/** Format rest types */
class RestTypeFormatter implements SubTypeFormatter {}

/** Format hidden/internal types */
class HiddenTypeFormatter implements SubTypeFormatter {}

/** Format function types */
class FunctionTypeFormatter implements SubTypeFormatter {}

/** Format constructor types */
class ConstructorTypeFormatter implements SubTypeFormatter {}

/** Format primitive union types */
class PrimitiveUnionTypeFormatter implements SubTypeFormatter {}

Formatter Infrastructure

Chain and specialized formatters that manage the formatting process.

/** Chains multiple formatters together */
class ChainTypeFormatter implements TypeFormatter, MutableTypeFormatter {
  constructor(formatters: SubTypeFormatter[]);
  addTypeFormatter(formatter: SubTypeFormatter): void;
}

/** Handles circular type references */
class CircularReferenceTypeFormatter implements TypeFormatter {
  constructor(childTypeFormatter: TypeFormatter);
}

Type System Integration

The formatter system works with the complete internal type representation.

/** Abstract base class for all internal types */
abstract class BaseType {
  abstract getId(): string;
  getName(): string;
}

Major Type Classes:

  • StringType, NumberType, BooleanType - Primitive types
  • ObjectType - Object types with properties
  • ArrayType - Array types
  • UnionType, IntersectionType - Composite types
  • LiteralType - Literal value types
  • EnumType - Enum types
  • FunctionType - Function types
  • DefinitionType - Referenced definitions
  • AliasType - Type aliases
  • AnnotatedType - Types with JSDoc annotations

Schema Generation Examples

Object Type Formatting:

// Internal ObjectType representation
const userType = new ObjectType("User", [
  new Property("id", new NumberType(), false),
  new Property("name", new StringType(), false), 
  new Property("email", new StringType(), true) // optional
]);

// Generated JSON Schema
const definition = formatter.getDefinition(userType);
// Result:
{
  "type": "object",
  "properties": {
    "id": { "type": "number" },
    "name": { "type": "string" },
    "email": { "type": "string" }
  },
  "required": ["id", "name"],
  "additionalProperties": false
}

Union Type Formatting:

// Internal UnionType representation  
const statusType = new UnionType([
  new LiteralType("pending"),
  new LiteralType("completed"),
  new LiteralType("failed")
]);

// Generated JSON Schema
const definition = formatter.getDefinition(statusType);
// Result:
{
  "type": "string",
  "enum": ["pending", "completed", "failed"]
}

Annotation Integration

Formatters integrate with annotation readers to include JSDoc metadata in schemas.

/** Formatter that processes JSDoc annotations */
class AnnotatedTypeFormatter implements SubTypeFormatter {
  supportsType(type: BaseType): boolean;
  getDefinition(type: AnnotatedType): Definition;
  getChildren(type: AnnotatedType): BaseType[];
}

Annotation Example:

// TypeScript with JSDoc
interface User {
  /** @format email */
  email: string;
  
  /** @minimum 18 @maximum 120 */
  age: number;
}

// Generated schema with annotations
{
  "type": "object", 
  "properties": {
    "email": { 
      "type": "string", 
      "format": "email" 
    },
    "age": { 
      "type": "number", 
      "minimum": 18, 
      "maximum": 120 
    }
  }
}

Configuration Impact

Formatter behavior is controlled by configuration options.

interface Config {
  /** Sort object properties alphabetically */
  sortProps?: boolean;
  /** Minify generated schema */
  minify?: boolean;
  /** Enforce strict tuple types */
  strictTuples?: boolean;
  /** Allow additional properties */
  additionalProperties?: boolean;
  /** How to handle function types */
  functions?: "fail" | "comment" | "hide";
  /** Additional validation keywords */
  extraTags?: string[];
  /** Generate markdown descriptions */
  markdownDescription?: boolean;
}

Configuration Effects:

  • sortProps: true - Properties appear in alphabetical order
  • strictTuples: true - Tuples have "additionalItems": false
  • additionalProperties: false - Objects reject extra properties
  • functions: "comment" - Functions become schema comments
  • extraTags - Include custom validation keywords from JSDoc

Install with Tessl CLI

npx tessl i tessl/npm-ts-json-schema-generator

docs

ast-parsing.md

cli-usage.md

custom-extensions.md

index.md

program-management.md

schema-generation.md

type-formatting.md

tile.json