or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdcore-conversion.mdindex.mdschema-transforms.mdtypescript-utilities.md

typescript-utilities.mddocs/

0

# TypeScript AST Utilities

1

2

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.

3

4

## Capabilities

5

6

### AST Conversion Functions

7

8

Core functions for converting between TypeScript AST nodes and source code strings.

9

10

```typescript { .api }

11

/**

12

* Convert TypeScript AST nodes to formatted source code string

13

* @param ast - Array of TypeScript AST nodes to convert

14

* @param options - Formatting and output options

15

* @returns Formatted TypeScript source code string

16

*/

17

function astToString(

18

ast: ts.Node[],

19

options?: AstToStringOptions

20

): string;

21

22

interface AstToStringOptions {

23

/** TypeScript formatting options */

24

formatOptions?: FormatCodeSettings;

25

/** Custom banner text to prepend */

26

banner?: string;

27

/** Custom footer text to append */

28

footer?: string;

29

}

30

31

/**

32

* Parse TypeScript source code string to AST nodes

33

* @param source - TypeScript source code string

34

* @returns Array of parsed AST nodes

35

*/

36

function stringToAST(source: string): unknown[];

37

```

38

39

**Usage Examples:**

40

41

```typescript

42

import { astToString, stringToAST } from "openapi-typescript";

43

44

// Convert AST to string with custom formatting

45

const sourceCode = astToString(astNodes, {

46

formatOptions: {

47

indentSize: 2,

48

insertSpaceAfterCommaDelimiter: true,

49

},

50

banner: "/* Custom header */",

51

footer: "/* Custom footer */"

52

});

53

54

// Parse TypeScript code to AST

55

const parsedNodes = stringToAST(`

56

interface User {

57

id: string;

58

name: string;

59

}

60

`);

61

```

62

63

### TypeScript Type Constants

64

65

Pre-built TypeScript AST nodes for common primitive types.

66

67

```typescript { .api }

68

/** Boolean keyword type node */

69

const BOOLEAN: ts.TypeNode;

70

71

/** False literal type node */

72

const FALSE: ts.TypeNode;

73

74

/** Never keyword type node */

75

const NEVER: ts.TypeNode;

76

77

/** Null literal type node */

78

const NULL: ts.TypeNode;

79

80

/** Number keyword type node */

81

const NUMBER: ts.TypeNode;

82

83

/** String keyword type node */

84

const STRING: ts.TypeNode;

85

86

/** True literal type node */

87

const TRUE: ts.TypeNode;

88

89

/** Undefined keyword type node */

90

const UNDEFINED: ts.TypeNode;

91

92

/** Unknown keyword type node */

93

const UNKNOWN: ts.TypeNode;

94

95

/** Question token for optional properties */

96

const QUESTION_TOKEN: ts.QuestionToken;

97

```

98

99

**Usage Example:**

100

101

```typescript

102

import { STRING, NUMBER, BOOLEAN, QUESTION_TOKEN } from "openapi-typescript";

103

104

// Use pre-built type nodes

105

const stringType = STRING;

106

const numberType = NUMBER;

107

const booleanType = BOOLEAN;

108

```

109

110

### Type Creation Utilities

111

112

Functions for creating complex TypeScript type nodes from values and other types.

113

114

```typescript { .api }

115

/**

116

* Convert JavaScript value to TypeScript literal type node

117

* @param value - JavaScript value to convert

118

* @returns TypeScript literal type node

119

*/

120

function tsLiteral(value: unknown): ts.TypeNode;

121

122

/**

123

* Create union type from array of type nodes

124

* @param types - Array of TypeScript type nodes

125

* @returns Union type node or single type if array has one element

126

*/

127

function tsUnion(types: ts.TypeNode[]): ts.TypeNode;

128

129

/**

130

* Create intersection type from array of type nodes

131

* @param types - Array of TypeScript type nodes

132

* @returns Intersection type node or single type if array has one element

133

*/

134

function tsIntersection(types: ts.TypeNode[]): ts.TypeNode;

135

136

/**

137

* Create nullable type (union with undefined)

138

* @param types - Base type nodes to make nullable

139

* @returns Union type with undefined added

140

*/

141

function tsNullable(types: ts.TypeNode[]): ts.TypeNode;

142

```

143

144

**Usage Examples:**

145

146

```typescript

147

import { tsLiteral, tsUnion, tsIntersection, tsNullable } from "openapi-typescript";

148

149

// Create literal types

150

const stringLiteral = tsLiteral("hello");

151

const numberLiteral = tsLiteral(42);

152

const booleanLiteral = tsLiteral(true);

153

154

// Create union type: string | number | boolean

155

const unionType = tsUnion([STRING, NUMBER, BOOLEAN]);

156

157

// Create intersection type: BaseUser & AdminUser

158

const intersectionType = tsIntersection([baseUserType, adminUserType]);

159

160

// Create nullable type: string | undefined

161

const nullableString = tsNullable([STRING]);

162

```

163

164

### Utility Type Generators

165

166

Functions for creating TypeScript utility types like Record, Omit, and Required.

167

168

```typescript { .api }

169

/**

170

* Create Record utility type

171

* @param key - Key type node

172

* @param value - Value type node

173

* @returns Record<K, V> type reference

174

*/

175

function tsRecord(key: ts.TypeNode, value: ts.TypeNode): ts.TypeNode;

176

177

/**

178

* Create Omit utility type

179

* @param type - Base type node

180

* @param keys - Array of key names to omit

181

* @returns Omit<T, K> type reference

182

*/

183

function tsOmit(type: ts.TypeNode, keys: string[]): ts.TypeNode;

184

185

/**

186

* Create Required utility type

187

* @param type - Base type node

188

* @param keys - Array of key names to make required

189

* @param injectFooter - Nodes to inject after type (needed for type helper)

190

* @returns Required<T> or Pick<Required<T>, K> type reference

191

*/

192

function tsWithRequired(

193

type: ts.TypeNode,

194

keys: string[],

195

injectFooter: ts.Node[]

196

): ts.TypeNode;

197

198

/**

199

* Create readonly array type

200

* @param type - Element type node

201

* @param injectFooter - Optional nodes to inject after type

202

* @returns readonly T[] type node

203

*/

204

function tsReadonlyArray(type: ts.TypeNode, injectFooter?: ts.Node[]): ts.TypeNode;

205

```

206

207

**Usage Examples:**

208

209

```typescript

210

import { tsRecord, tsOmit, tsWithRequired, tsReadonlyArray } from "openapi-typescript";

211

212

// Create Record<string, any>

213

const recordType = tsRecord(STRING, UNKNOWN);

214

215

// Create Omit<User, 'password'>

216

const omitType = tsOmit(userType, ["password"]);

217

218

// Create Required<User> or Pick<Required<User>, 'name' | 'email'>

219

const requiredType = tsWithRequired(userType, ["name", "email"], injectFooter);

220

221

// Create readonly string[]

222

const readonlyArrayType = tsReadonlyArray(STRING);

223

```

224

225

### Declaration and Modifier Utilities

226

227

Functions for creating TypeScript declarations and modifiers.

228

229

```typescript { .api }

230

/**

231

* Create TypeScript modifier arrays

232

* @param modifiers - Modifier configuration object

233

* @returns Array of TypeScript modifier nodes

234

*/

235

function tsModifiers(modifiers: {

236

export?: boolean;

237

readonly?: boolean;

238

}): ts.Modifier[];

239

240

/**

241

* Create property name/index node for object properties

242

* @param index - Property name as string or number

243

* @returns TypeScript property name node

244

*/

245

function tsPropertyIndex(index: string | number): ts.PropertyName;

246

```

247

248

**Usage Examples:**

249

250

```typescript

251

import { tsModifiers, tsPropertyIndex } from "openapi-typescript";

252

253

// Create export modifier

254

const exportModifier = tsModifiers({ export: true });

255

256

// Create readonly export modifiers

257

const readonlyExportModifiers = tsModifiers({

258

export: true,

259

readonly: true

260

});

261

262

// Create property names

263

const stringProp = tsPropertyIndex("userName");

264

const numberProp = tsPropertyIndex(42);

265

```

266

267

### Enum and Array Utilities

268

269

Functions for creating TypeScript enums and array literal expressions.

270

271

```typescript { .api }

272

/**

273

* Create TypeScript enum declaration

274

* @param name - Enum name

275

* @param keys - Array of enum key names

276

* @param values - Optional array of enum values

277

* @param options - Enum creation options

278

* @returns TypeScript enum declaration

279

*/

280

function tsEnum(

281

name: string,

282

keys: (string | number)[],

283

values?: (string | number)[],

284

options?: { export?: boolean; shouldCache?: boolean }

285

): ts.EnumDeclaration;

286

287

/**

288

* Create enum member declarations

289

* @param value - Member value (string or number)

290

* @param metadata - Member metadata (name, description)

291

* @returns Array of TypeScript enum member nodes

292

*/

293

function tsEnumMember(

294

value: string | number,

295

metadata?: { name?: string; description?: string | null }

296

): ts.EnumMember[];

297

298

/**

299

* Create array literal expression as variable declaration

300

* @param name - Variable name

301

* @param elementType - Type of array elements

302

* @param values - Array of values (string or number)

303

* @param options - Array creation options

304

* @returns TypeScript variable statement with array literal

305

*/

306

function tsArrayLiteralExpression(

307

name: string,

308

elementType: ts.TypeNode,

309

values: (string | number)[],

310

options?: { export?: boolean; readonly?: boolean; injectFooter?: ts.Node[] }

311

): ts.VariableStatement;

312

313

/** Global enum declaration cache to prevent duplicates */

314

const enumCache: Map<string, ts.EnumDeclaration>;

315

```

316

317

**Usage Examples:**

318

319

```typescript

320

import { tsEnum, tsEnumMember, tsArrayLiteralExpression } from "openapi-typescript";

321

322

// Create enum with string values

323

const statusEnum = tsEnum(

324

"Status",

325

["ACTIVE", "INACTIVE", "PENDING"],

326

["active", "inactive", "pending"],

327

{ export: true }

328

);

329

330

// Create enum members

331

const enumMembers = tsEnumMember("active", {

332

name: "ACTIVE",

333

description: "User is active"

334

});

335

336

// Create array literal

337

const colorsArray = tsArrayLiteralExpression(

338

"COLORS",

339

STRING, // element type

340

["red", "green", "blue"],

341

{ export: true, readonly: true }

342

);

343

```

344

345

### Regular Expressions and Validation

346

347

Constants and utilities for JavaScript/TypeScript identifier validation.

348

349

```typescript { .api }

350

/** Regular expression for valid JavaScript property names */

351

const JS_PROPERTY_INDEX_RE: RegExp;

352

353

/** Regular expression for invalid characters in enum names */

354

const JS_ENUM_INVALID_CHARS_RE: RegExp;

355

356

/** Regular expression for invalid characters in property names */

357

const JS_PROPERTY_INDEX_INVALID_CHARS_RE: RegExp;

358

359

/** Map of special characters to their replacements */

360

const SPECIAL_CHARACTER_MAP: Record<string, string>;

361

```

362

363

**Usage Examples:**

364

365

```typescript

366

import {

367

JS_PROPERTY_INDEX_RE,

368

JS_ENUM_INVALID_CHARS_RE,

369

SPECIAL_CHARACTER_MAP

370

} from "openapi-typescript";

371

372

// Check if string is valid property name

373

const isValidProperty = JS_PROPERTY_INDEX_RE.test("userName"); // true

374

const isInvalidProperty = JS_PROPERTY_INDEX_RE.test("user-name"); // false

375

376

// Clean enum names

377

const cleanEnumName = "some+enum".replace(JS_ENUM_INVALID_CHARS_RE, "_");

378

379

// Replace special characters

380

const cleaned = "some+thing".replace("+", SPECIAL_CHARACTER_MAP["+"]);

381

```

382

383

### Type Checking and Manipulation

384

385

Utilities for analyzing and manipulating TypeScript type nodes.

386

387

```typescript { .api }

388

/**

389

* Check if TypeScript type node represents a primitive type

390

* @param type - TypeScript type node to check

391

* @returns True if type is primitive (string, number, boolean, etc.)

392

*/

393

function tsIsPrimitive(type: ts.TypeNode): boolean;

394

395

/**

396

* Remove duplicate types from array of type nodes

397

* @param types - Array of TypeScript type nodes

398

* @returns Array with duplicate types removed

399

*/

400

function tsDedupe(types: ts.TypeNode[]): ts.TypeNode[];

401

```

402

403

**Usage Examples:**

404

405

```typescript

406

import { tsIsPrimitive, tsDedupe } from "openapi-typescript";

407

408

// Check if type is primitive

409

const isPrimitive = tsIsPrimitive(STRING); // true

410

const isObject = tsIsPrimitive(objectType); // false

411

412

// Remove duplicates from type array

413

const uniqueTypes = tsDedupe([STRING, NUMBER, STRING, BOOLEAN]);

414

// Result: [STRING, NUMBER, BOOLEAN]

415

```

416

417

### JSDoc Comment Utilities

418

419

Functions for adding JSDoc comments to TypeScript nodes.

420

421

```typescript { .api }

422

/**

423

* Schema object interface for JSDoc comment generation

424

*/

425

interface AnnotatedSchemaObject {

426

const?: unknown;

427

default?: unknown;

428

deprecated?: boolean;

429

description?: string;

430

enum?: unknown[];

431

example?: string;

432

examples?: unknown;

433

format?: string;

434

nullable?: boolean;

435

summary?: string;

436

title?: string;

437

type?: string | string[];

438

}

439

440

/**

441

* Add JSDoc comment to TypeScript property signature

442

* @param schemaObject - Schema object with metadata

443

* @param node - TypeScript property signature to annotate

444

* @returns void (modifies node in place)

445

*/

446

function addJSDocComment(

447

schemaObject: AnnotatedSchemaObject,

448

node: ts.PropertySignature

449

): void;

450

```

451

452

**Usage Example:**

453

454

```typescript

455

import { addJSDocComment } from "openapi-typescript";

456

457

const schemaMetadata = {

458

description: "User's email address",

459

format: "email",

460

example: "user@example.com"

461

};

462

463

// Add JSDoc comment to property

464

addJSDocComment(schemaMetadata, propertyNode);

465

```

466

467

### OpenAPI Reference Utilities

468

469

Utilities for creating TypeScript reference types from OpenAPI $ref pointers.

470

471

```typescript { .api }

472

/**

473

* Create TypeScript reference type from OpenAPI $ref path

474

* @param path - OpenAPI $ref path (e.g., "#/components/schemas/User")

475

* @param resolved - Optional resolved reference metadata

476

* @returns TypeScript type reference node

477

*/

478

function oapiRef(path: string, resolved?: OapiRefResolved): ts.TypeNode;

479

480

interface OapiRefResolved {

481

schemaObject: SchemaObject;

482

isComponent: boolean;

483

}

484

```

485

486

**Usage Example:**

487

488

```typescript

489

import { oapiRef } from "openapi-typescript";

490

491

// Create reference to component schema

492

const userRef = oapiRef("#/components/schemas/User");

493

494

// Create reference with resolved metadata

495

const resolvedRef = oapiRef("#/components/schemas/Product", {

496

schemaObject: productSchema,

497

isComponent: true

498

});

499

```

500

501

### General Utilities

502

503

Additional utilities for schema processing, debugging, and OpenAPI reference handling.

504

505

```typescript { .api }

506

/**

507

* Debug logging with color groups and timing

508

* @param msg - Debug message to log

509

* @param group - Optional group for color coding (redoc, lint, bundle, ts)

510

* @param time - Optional timing information in milliseconds

511

* @returns void

512

*/

513

function debug(msg: string, group?: string, time?: number): void;

514

515

/**

516

* Format error messages with color

517

* @param msg - Error message to format

518

* @returns Formatted error message string

519

*/

520

function error(msg: string): string;

521

522

/**

523

* Format warning messages with color

524

* @param msg - Warning message to format

525

* @param silent - Whether to suppress output

526

* @returns void

527

*/

528

function warn(msg: string, silent?: boolean): void;

529

530

/**

531

* Format performance timing in readable format

532

* @param t - Time in milliseconds

533

* @returns Formatted time string (e.g., "1.23s", "456ms")

534

*/

535

function formatTime(t: number): string;

536

537

/**

538

* Create OpenAPI reference pointer from path parts

539

* @param parts - Array of path components (strings, numbers, etc.)

540

* @returns OpenAPI $ref pointer string

541

*/

542

function createRef(parts: (number | string | undefined | null)[]): string;

543

544

/**

545

* Resolve OpenAPI $ref pointers within a schema

546

* @param schema - OpenAPI document to resolve within

547

* @param $ref - Reference pointer to resolve

548

* @param options - Resolution options

549

* @returns Resolved object of type T

550

*/

551

function resolveRef<T>(

552

schema: OpenAPI3,

553

$ref: string,

554

options?: { silent?: boolean }

555

): T;

556

557

/**

558

* Type-safe Object.entries with filtering capabilities

559

* @param obj - Object or array-like object to get entries from

560

* @param options - Filtering and sorting options

561

* @returns Array of [key, value] tuples

562

*/

563

function getEntries<T>(

564

obj: ArrayLike<T> | Record<string, T>,

565

options?: {

566

alphabetize?: boolean;

567

excludeDeprecated?: boolean;

568

}

569

): [string, T][];

570

571

/**

572

* Scan OpenAPI schema for discriminator objects

573

* @param schema - OpenAPI document to scan

574

* @param options - Scanning options

575

* @returns Map of discriminator objects by schema path

576

*/

577

function scanDiscriminators(

578

schema: OpenAPI3,

579

options: OpenAPITSOptions

580

): Map<string, DiscriminatorObject>;

581

582

/**

583

* Walk JSON-serializable object recursively with visitor function

584

* @param obj - Object to walk recursively

585

* @param cb - Callback function called for each object

586

* @param path - Current path (internal parameter)

587

* @returns void

588

*/

589

function walk(

590

obj: unknown,

591

cb: (value: Record<string, unknown>, path: (string | number)[]) => void,

592

path?: (string | number)[]

593

): void;

594

595

/**

596

* Create discriminator property for polymorphic schemas

597

* @param discriminator - Discriminator object from OpenAPI

598

* @param options - Property creation options

599

* @returns TypeScript property signature for discriminator

600

*/

601

function createDiscriminatorProperty(

602

discriminator: DiscriminatorObject,

603

options: { path: string; readonly?: boolean }

604

): ts.TypeElement;

605

606

/** Color formatting utilities (re-export from ansi-colors) */

607

const c: typeof import("ansi-colors");

608

```

609

610

**Usage Examples:**

611

612

```typescript

613

import {

614

debug,

615

error,

616

warn,

617

formatTime,

618

createRef,

619

resolveRef,

620

getEntries,

621

c

622

} from "openapi-typescript";

623

624

// Debug logging with groups

625

debug("Processing schema", "ts", 123.45);

626

627

// Error formatting

628

const errorMsg = error("Schema validation failed");

629

630

// Warning with silent option

631

warn("Deprecated property found", false);

632

633

// Format timing

634

const timeStr = formatTime(1234.56); // "1.23s"

635

636

// Create reference pointer

637

const ref = createRef(["components", "schemas", "User"]); // "#/components/schemas/User"

638

639

// Resolve reference

640

const resolvedSchema = resolveRef(openApiDoc, "#/components/schemas/User");

641

642

// Get filtered entries

643

const entries = getEntries(componentsObject, {

644

alphabetize: true,

645

excludeDeprecated: true

646

});

647

648

// Use color formatting

649

console.log(c.green("Success:"), c.blue("Types generated"));

650

```