Convert OpenAPI 3.0 & 3.1 schemas to TypeScript type definitions
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Comprehensive utilities for creating, manipulating, and converting TypeScript AST nodes. These building blocks enable custom transform functions and provide low-level control over TypeScript code generation.
Core functions for converting between TypeScript AST nodes and source code strings.
/**
* Convert TypeScript AST nodes to formatted source code string
* @param ast - Array of TypeScript AST nodes to convert
* @param options - Formatting and output options
* @returns Formatted TypeScript source code string
*/
function astToString(
ast: ts.Node[],
options?: AstToStringOptions
): string;
interface AstToStringOptions {
/** TypeScript formatting options */
formatOptions?: FormatCodeSettings;
/** Custom banner text to prepend */
banner?: string;
/** Custom footer text to append */
footer?: string;
}
/**
* Parse TypeScript source code string to AST nodes
* @param source - TypeScript source code string
* @returns Array of parsed AST nodes
*/
function stringToAST(source: string): unknown[];Usage Examples:
import { astToString, stringToAST } from "openapi-typescript";
// Convert AST to string with custom formatting
const sourceCode = astToString(astNodes, {
formatOptions: {
indentSize: 2,
insertSpaceAfterCommaDelimiter: true,
},
banner: "/* Custom header */",
footer: "/* Custom footer */"
});
// Parse TypeScript code to AST
const parsedNodes = stringToAST(`
interface User {
id: string;
name: string;
}
`);Pre-built TypeScript AST nodes for common primitive types.
/** Boolean keyword type node */
const BOOLEAN: ts.TypeNode;
/** False literal type node */
const FALSE: ts.TypeNode;
/** Never keyword type node */
const NEVER: ts.TypeNode;
/** Null literal type node */
const NULL: ts.TypeNode;
/** Number keyword type node */
const NUMBER: ts.TypeNode;
/** String keyword type node */
const STRING: ts.TypeNode;
/** True literal type node */
const TRUE: ts.TypeNode;
/** Undefined keyword type node */
const UNDEFINED: ts.TypeNode;
/** Unknown keyword type node */
const UNKNOWN: ts.TypeNode;
/** Question token for optional properties */
const QUESTION_TOKEN: ts.QuestionToken;Usage Example:
import { STRING, NUMBER, BOOLEAN, QUESTION_TOKEN } from "openapi-typescript";
// Use pre-built type nodes
const stringType = STRING;
const numberType = NUMBER;
const booleanType = BOOLEAN;Functions for creating complex TypeScript type nodes from values and other types.
/**
* Convert JavaScript value to TypeScript literal type node
* @param value - JavaScript value to convert
* @returns TypeScript literal type node
*/
function tsLiteral(value: unknown): ts.TypeNode;
/**
* Create union type from array of type nodes
* @param types - Array of TypeScript type nodes
* @returns Union type node or single type if array has one element
*/
function tsUnion(types: ts.TypeNode[]): ts.TypeNode;
/**
* Create intersection type from array of type nodes
* @param types - Array of TypeScript type nodes
* @returns Intersection type node or single type if array has one element
*/
function tsIntersection(types: ts.TypeNode[]): ts.TypeNode;
/**
* Create nullable type (union with undefined)
* @param types - Base type nodes to make nullable
* @returns Union type with undefined added
*/
function tsNullable(types: ts.TypeNode[]): ts.TypeNode;Usage Examples:
import { tsLiteral, tsUnion, tsIntersection, tsNullable } from "openapi-typescript";
// Create literal types
const stringLiteral = tsLiteral("hello");
const numberLiteral = tsLiteral(42);
const booleanLiteral = tsLiteral(true);
// Create union type: string | number | boolean
const unionType = tsUnion([STRING, NUMBER, BOOLEAN]);
// Create intersection type: BaseUser & AdminUser
const intersectionType = tsIntersection([baseUserType, adminUserType]);
// Create nullable type: string | undefined
const nullableString = tsNullable([STRING]);Functions for creating TypeScript utility types like Record, Omit, and Required.
/**
* Create Record utility type
* @param key - Key type node
* @param value - Value type node
* @returns Record<K, V> type reference
*/
function tsRecord(key: ts.TypeNode, value: ts.TypeNode): ts.TypeNode;
/**
* Create Omit utility type
* @param type - Base type node
* @param keys - Array of key names to omit
* @returns Omit<T, K> type reference
*/
function tsOmit(type: ts.TypeNode, keys: string[]): ts.TypeNode;
/**
* Create Required utility type
* @param type - Base type node
* @param keys - Array of key names to make required
* @param injectFooter - Nodes to inject after type (needed for type helper)
* @returns Required<T> or Pick<Required<T>, K> type reference
*/
function tsWithRequired(
type: ts.TypeNode,
keys: string[],
injectFooter: ts.Node[]
): ts.TypeNode;
/**
* Create readonly array type
* @param type - Element type node
* @param injectFooter - Optional nodes to inject after type
* @returns readonly T[] type node
*/
function tsReadonlyArray(type: ts.TypeNode, injectFooter?: ts.Node[]): ts.TypeNode;Usage Examples:
import { tsRecord, tsOmit, tsWithRequired, tsReadonlyArray } from "openapi-typescript";
// Create Record<string, any>
const recordType = tsRecord(STRING, UNKNOWN);
// Create Omit<User, 'password'>
const omitType = tsOmit(userType, ["password"]);
// Create Required<User> or Pick<Required<User>, 'name' | 'email'>
const requiredType = tsWithRequired(userType, ["name", "email"], injectFooter);
// Create readonly string[]
const readonlyArrayType = tsReadonlyArray(STRING);Functions for creating TypeScript declarations and modifiers.
/**
* Create TypeScript modifier arrays
* @param modifiers - Modifier configuration object
* @returns Array of TypeScript modifier nodes
*/
function tsModifiers(modifiers: {
export?: boolean;
readonly?: boolean;
}): ts.Modifier[];
/**
* Create property name/index node for object properties
* @param index - Property name as string or number
* @returns TypeScript property name node
*/
function tsPropertyIndex(index: string | number): ts.PropertyName;Usage Examples:
import { tsModifiers, tsPropertyIndex } from "openapi-typescript";
// Create export modifier
const exportModifier = tsModifiers({ export: true });
// Create readonly export modifiers
const readonlyExportModifiers = tsModifiers({
export: true,
readonly: true
});
// Create property names
const stringProp = tsPropertyIndex("userName");
const numberProp = tsPropertyIndex(42);Functions for creating TypeScript enums and array literal expressions.
/**
* Create TypeScript enum declaration
* @param name - Enum name
* @param keys - Array of enum key names
* @param values - Optional array of enum values
* @param options - Enum creation options
* @returns TypeScript enum declaration
*/
function tsEnum(
name: string,
keys: (string | number)[],
values?: (string | number)[],
options?: { export?: boolean; shouldCache?: boolean }
): ts.EnumDeclaration;
/**
* Create enum member declarations
* @param value - Member value (string or number)
* @param metadata - Member metadata (name, description)
* @returns Array of TypeScript enum member nodes
*/
function tsEnumMember(
value: string | number,
metadata?: { name?: string; description?: string | null }
): ts.EnumMember[];
/**
* Create array literal expression as variable declaration
* @param name - Variable name
* @param elementType - Type of array elements
* @param values - Array of values (string or number)
* @param options - Array creation options
* @returns TypeScript variable statement with array literal
*/
function tsArrayLiteralExpression(
name: string,
elementType: ts.TypeNode,
values: (string | number)[],
options?: { export?: boolean; readonly?: boolean; injectFooter?: ts.Node[] }
): ts.VariableStatement;
/** Global enum declaration cache to prevent duplicates */
const enumCache: Map<string, ts.EnumDeclaration>;Usage Examples:
import { tsEnum, tsEnumMember, tsArrayLiteralExpression } from "openapi-typescript";
// Create enum with string values
const statusEnum = tsEnum(
"Status",
["ACTIVE", "INACTIVE", "PENDING"],
["active", "inactive", "pending"],
{ export: true }
);
// Create enum members
const enumMembers = tsEnumMember("active", {
name: "ACTIVE",
description: "User is active"
});
// Create array literal
const colorsArray = tsArrayLiteralExpression(
"COLORS",
STRING, // element type
["red", "green", "blue"],
{ export: true, readonly: true }
);Constants and utilities for JavaScript/TypeScript identifier validation.
/** Regular expression for valid JavaScript property names */
const JS_PROPERTY_INDEX_RE: RegExp;
/** Regular expression for invalid characters in enum names */
const JS_ENUM_INVALID_CHARS_RE: RegExp;
/** Regular expression for invalid characters in property names */
const JS_PROPERTY_INDEX_INVALID_CHARS_RE: RegExp;
/** Map of special characters to their replacements */
const SPECIAL_CHARACTER_MAP: Record<string, string>;Usage Examples:
import {
JS_PROPERTY_INDEX_RE,
JS_ENUM_INVALID_CHARS_RE,
SPECIAL_CHARACTER_MAP
} from "openapi-typescript";
// Check if string is valid property name
const isValidProperty = JS_PROPERTY_INDEX_RE.test("userName"); // true
const isInvalidProperty = JS_PROPERTY_INDEX_RE.test("user-name"); // false
// Clean enum names
const cleanEnumName = "some+enum".replace(JS_ENUM_INVALID_CHARS_RE, "_");
// Replace special characters
const cleaned = "some+thing".replace("+", SPECIAL_CHARACTER_MAP["+"]);Utilities for analyzing and manipulating TypeScript type nodes.
/**
* Check if TypeScript type node represents a primitive type
* @param type - TypeScript type node to check
* @returns True if type is primitive (string, number, boolean, etc.)
*/
function tsIsPrimitive(type: ts.TypeNode): boolean;
/**
* Remove duplicate types from array of type nodes
* @param types - Array of TypeScript type nodes
* @returns Array with duplicate types removed
*/
function tsDedupe(types: ts.TypeNode[]): ts.TypeNode[];Usage Examples:
import { tsIsPrimitive, tsDedupe } from "openapi-typescript";
// Check if type is primitive
const isPrimitive = tsIsPrimitive(STRING); // true
const isObject = tsIsPrimitive(objectType); // false
// Remove duplicates from type array
const uniqueTypes = tsDedupe([STRING, NUMBER, STRING, BOOLEAN]);
// Result: [STRING, NUMBER, BOOLEAN]Functions for adding JSDoc comments to TypeScript nodes.
/**
* Schema object interface for JSDoc comment generation
*/
interface AnnotatedSchemaObject {
const?: unknown;
default?: unknown;
deprecated?: boolean;
description?: string;
enum?: unknown[];
example?: string;
examples?: unknown;
format?: string;
nullable?: boolean;
summary?: string;
title?: string;
type?: string | string[];
}
/**
* Add JSDoc comment to TypeScript property signature
* @param schemaObject - Schema object with metadata
* @param node - TypeScript property signature to annotate
* @returns void (modifies node in place)
*/
function addJSDocComment(
schemaObject: AnnotatedSchemaObject,
node: ts.PropertySignature
): void;Usage Example:
import { addJSDocComment } from "openapi-typescript";
const schemaMetadata = {
description: "User's email address",
format: "email",
example: "user@example.com"
};
// Add JSDoc comment to property
addJSDocComment(schemaMetadata, propertyNode);Utilities for creating TypeScript reference types from OpenAPI $ref pointers.
/**
* Create TypeScript reference type from OpenAPI $ref path
* @param path - OpenAPI $ref path (e.g., "#/components/schemas/User")
* @param resolved - Optional resolved reference metadata
* @returns TypeScript type reference node
*/
function oapiRef(path: string, resolved?: OapiRefResolved): ts.TypeNode;
interface OapiRefResolved {
schemaObject: SchemaObject;
isComponent: boolean;
}Usage Example:
import { oapiRef } from "openapi-typescript";
// Create reference to component schema
const userRef = oapiRef("#/components/schemas/User");
// Create reference with resolved metadata
const resolvedRef = oapiRef("#/components/schemas/Product", {
schemaObject: productSchema,
isComponent: true
});Additional utilities for schema processing, debugging, and OpenAPI reference handling.
/**
* Debug logging with color groups and timing
* @param msg - Debug message to log
* @param group - Optional group for color coding (redoc, lint, bundle, ts)
* @param time - Optional timing information in milliseconds
* @returns void
*/
function debug(msg: string, group?: string, time?: number): void;
/**
* Format error messages with color
* @param msg - Error message to format
* @returns Formatted error message string
*/
function error(msg: string): string;
/**
* Format warning messages with color
* @param msg - Warning message to format
* @param silent - Whether to suppress output
* @returns void
*/
function warn(msg: string, silent?: boolean): void;
/**
* Format performance timing in readable format
* @param t - Time in milliseconds
* @returns Formatted time string (e.g., "1.23s", "456ms")
*/
function formatTime(t: number): string;
/**
* Create OpenAPI reference pointer from path parts
* @param parts - Array of path components (strings, numbers, etc.)
* @returns OpenAPI $ref pointer string
*/
function createRef(parts: (number | string | undefined | null)[]): string;
/**
* Resolve OpenAPI $ref pointers within a schema
* @param schema - OpenAPI document to resolve within
* @param $ref - Reference pointer to resolve
* @param options - Resolution options
* @returns Resolved object of type T
*/
function resolveRef<T>(
schema: OpenAPI3,
$ref: string,
options?: { silent?: boolean }
): T;
/**
* Type-safe Object.entries with filtering capabilities
* @param obj - Object or array-like object to get entries from
* @param options - Filtering and sorting options
* @returns Array of [key, value] tuples
*/
function getEntries<T>(
obj: ArrayLike<T> | Record<string, T>,
options?: {
alphabetize?: boolean;
excludeDeprecated?: boolean;
}
): [string, T][];
/**
* Scan OpenAPI schema for discriminator objects
* @param schema - OpenAPI document to scan
* @param options - Scanning options
* @returns Map of discriminator objects by schema path
*/
function scanDiscriminators(
schema: OpenAPI3,
options: OpenAPITSOptions
): Map<string, DiscriminatorObject>;
/**
* Walk JSON-serializable object recursively with visitor function
* @param obj - Object to walk recursively
* @param cb - Callback function called for each object
* @param path - Current path (internal parameter)
* @returns void
*/
function walk(
obj: unknown,
cb: (value: Record<string, unknown>, path: (string | number)[]) => void,
path?: (string | number)[]
): void;
/**
* Create discriminator property for polymorphic schemas
* @param discriminator - Discriminator object from OpenAPI
* @param options - Property creation options
* @returns TypeScript property signature for discriminator
*/
function createDiscriminatorProperty(
discriminator: DiscriminatorObject,
options: { path: string; readonly?: boolean }
): ts.TypeElement;
/** Color formatting utilities (re-export from ansi-colors) */
const c: typeof import("ansi-colors");Usage Examples:
import {
debug,
error,
warn,
formatTime,
createRef,
resolveRef,
getEntries,
c
} from "openapi-typescript";
// Debug logging with groups
debug("Processing schema", "ts", 123.45);
// Error formatting
const errorMsg = error("Schema validation failed");
// Warning with silent option
warn("Deprecated property found", false);
// Format timing
const timeStr = formatTime(1234.56); // "1.23s"
// Create reference pointer
const ref = createRef(["components", "schemas", "User"]); // "#/components/schemas/User"
// Resolve reference
const resolvedSchema = resolveRef(openApiDoc, "#/components/schemas/User");
// Get filtered entries
const entries = getEntries(componentsObject, {
alphabetize: true,
excludeDeprecated: true
});
// Use color formatting
console.log(c.green("Success:"), c.blue("Types generated"));Install with Tessl CLI
npx tessl i tessl/npm-openapi-typescript