or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

command-line-config.mdindex.mdlanguage-services.mdnode-factory-transformers.mdparser-ast.mdprogram-compilation.mdtranspilation.mdtype-checker.mdutilities-helpers.md

utilities-helpers.mddocs/

0

# Utilities and Helpers

1

2

Essential utility functions for working with TypeScript AST nodes, including type guards, text operations, and traversal helpers.

3

4

## Capabilities

5

6

### Type Guards

7

8

Functions that determine the type of AST nodes at runtime.

9

10

```typescript { .api }

11

/**

12

* Check if node is an identifier

13

* @param node - Node to test

14

* @returns True if node is an identifier

15

*/

16

function isIdentifier(node: Node): node is Identifier;

17

18

/**

19

* Check if node is a string literal

20

* @param node - Node to test

21

* @returns True if node is a string literal

22

*/

23

function isStringLiteral(node: Node): node is StringLiteral;

24

25

/**

26

* Check if node is a numeric literal

27

* @param node - Node to test

28

* @returns True if node is a numeric literal

29

*/

30

function isNumericLiteral(node: Node): node is NumericLiteral;

31

32

/**

33

* Check if node is a function declaration

34

* @param node - Node to test

35

* @returns True if node is a function declaration

36

*/

37

function isFunctionDeclaration(node: Node): node is FunctionDeclaration;

38

39

/**

40

* Check if node is a class declaration

41

* @param node - Node to test

42

* @returns True if node is a class declaration

43

*/

44

function isClassDeclaration(node: Node): node is ClassDeclaration;

45

46

/**

47

* Check if node is an interface declaration

48

* @param node - Node to test

49

* @returns True if node is an interface declaration

50

*/

51

function isInterfaceDeclaration(node: Node): node is InterfaceDeclaration;

52

53

/**

54

* Check if node is a variable declaration

55

* @param node - Node to test

56

* @returns True if node is a variable declaration

57

*/

58

function isVariableDeclaration(node: Node): node is VariableDeclaration;

59

60

/**

61

* Check if node is a method declaration

62

* @param node - Node to test

63

* @returns True if node is a method declaration

64

*/

65

function isMethodDeclaration(node: Node): node is MethodDeclaration;

66

67

/**

68

* Check if node is a property declaration

69

* @param node - Node to test

70

* @returns True if node is a property declaration

71

*/

72

function isPropertyDeclaration(node: Node): node is PropertyDeclaration;

73

74

/**

75

* Check if node is a parameter declaration

76

* @param node - Node to test

77

* @returns True if node is a parameter declaration

78

*/

79

function isParameterDeclaration(node: Node): node is ParameterDeclaration;

80

```

81

82

**Usage Examples:**

83

84

```typescript

85

import * as ts from "typescript";

86

87

const sourceFile = ts.createSourceFile(

88

"example.ts",

89

`

90

class User {

91

name: string;

92

constructor(name: string) {

93

this.name = name;

94

}

95

greet(): string {

96

return "Hello!";

97

}

98

}

99

`,

100

ts.ScriptTarget.Latest

101

);

102

103

function analyzeNode(node: ts.Node) {

104

if (ts.isClassDeclaration(node)) {

105

console.log(`Found class: ${node.name?.text}`);

106

107

for (const member of node.members) {

108

if (ts.isPropertyDeclaration(member)) {

109

console.log(` Property: ${member.name?.getText()}`);

110

} else if (ts.isMethodDeclaration(member)) {

111

console.log(` Method: ${member.name?.getText()}`);

112

} else if (ts.isConstructorDeclaration(member)) {

113

console.log(` Constructor with ${member.parameters.length} parameters`);

114

}

115

}

116

}

117

118

ts.forEachChild(node, analyzeNode);

119

}

120

121

analyzeNode(sourceFile);

122

```

123

124

### Expression Type Guards

125

126

Type guards for various expression types.

127

128

```typescript { .api }

129

/**

130

* Check if node is an expression

131

* @param node - Node to test

132

* @returns True if node is an expression

133

*/

134

function isExpression(node: Node): node is Expression;

135

136

/**

137

* Check if node is a call expression

138

* @param node - Node to test

139

* @returns True if node is a call expression

140

*/

141

function isCallExpression(node: Node): node is CallExpression;

142

143

/**

144

* Check if node is a property access expression

145

* @param node - Node to test

146

* @returns True if node is a property access expression

147

*/

148

function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression;

149

150

/**

151

* Check if node is an element access expression

152

* @param node - Node to test

153

* @returns True if node is an element access expression

154

*/

155

function isElementAccessExpression(node: Node): node is ElementAccessExpression;

156

157

/**

158

* Check if node is a binary expression

159

* @param node - Node to test

160

* @returns True if node is a binary expression

161

*/

162

function isBinaryExpression(node: Node): node is BinaryExpression;

163

164

/**

165

* Check if node is a conditional expression

166

* @param node - Node to test

167

* @returns True if node is a conditional expression

168

*/

169

function isConditionalExpression(node: Node): node is ConditionalExpression;

170

171

/**

172

* Check if node is an arrow function

173

* @param node - Node to test

174

* @returns True if node is an arrow function

175

*/

176

function isArrowFunction(node: Node): node is ArrowFunction;

177

178

/**

179

* Check if node is a template expression

180

* @param node - Node to test

181

* @returns True if node is a template expression

182

*/

183

function isTemplateExpression(node: Node): node is TemplateExpression;

184

185

/**

186

* Check if node is an object literal expression

187

* @param node - Node to test

188

* @returns True if node is an object literal expression

189

*/

190

function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression;

191

192

/**

193

* Check if node is an array literal expression

194

* @param node - Node to test

195

* @returns True if node is an array literal expression

196

*/

197

function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression;

198

```

199

200

### Statement Type Guards

201

202

Type guards for various statement types.

203

204

```typescript { .api }

205

/**

206

* Check if node is a statement

207

* @param node - Node to test

208

* @returns True if node is a statement

209

*/

210

function isStatement(node: Node): node is Statement;

211

212

/**

213

* Check if node is a block statement

214

* @param node - Node to test

215

* @returns True if node is a block statement

216

*/

217

function isBlock(node: Node): node is Block;

218

219

/**

220

* Check if node is an if statement

221

* @param node - Node to test

222

* @returns True if node is an if statement

223

*/

224

function isIfStatement(node: Node): node is IfStatement;

225

226

/**

227

* Check if node is a for statement

228

* @param node - Node to test

229

* @returns True if node is a for statement

230

*/

231

function isForStatement(node: Node): node is ForStatement;

232

233

/**

234

* Check if node is a while statement

235

* @param node - Node to test

236

* @returns True if node is a while statement

237

*/

238

function isWhileStatement(node: Node): node is WhileStatement;

239

240

/**

241

* Check if node is a return statement

242

* @param node - Node to test

243

* @returns True if node is a return statement

244

*/

245

function isReturnStatement(node: Node): node is ReturnStatement;

246

247

/**

248

* Check if node is a try statement

249

* @param node - Node to test

250

* @returns True if node is a try statement

251

*/

252

function isTryStatement(node: Node): node is TryStatement;

253

254

/**

255

* Check if node is a switch statement

256

* @param node - Node to test

257

* @returns True if node is a switch statement

258

*/

259

function isSwitchStatement(node: Node): node is SwitchStatement;

260

261

/**

262

* Check if node is an expression statement

263

* @param node - Node to test

264

* @returns True if node is an expression statement

265

*/

266

function isExpressionStatement(node: Node): node is ExpressionStatement;

267

268

/**

269

* Check if node is a variable statement

270

* @param node - Node to test

271

* @returns True if node is a variable statement

272

*/

273

function isVariableStatement(node: Node): node is VariableStatement;

274

```

275

276

### Type Node Guards

277

278

Type guards for TypeScript type annotations.

279

280

```typescript { .api }

281

/**

282

* Check if node is a type node

283

* @param node - Node to test

284

* @returns True if node is a type node

285

*/

286

function isTypeNode(node: Node): node is TypeNode;

287

288

/**

289

* Check if node is a type reference node

290

* @param node - Node to test

291

* @returns True if node is a type reference node

292

*/

293

function isTypeReferenceNode(node: Node): node is TypeReferenceNode;

294

295

/**

296

* Check if node is a union type node

297

* @param node - Node to test

298

* @returns True if node is a union type node

299

*/

300

function isUnionTypeNode(node: Node): node is UnionTypeNode;

301

302

/**

303

* Check if node is an intersection type node

304

* @param node - Node to test

305

* @returns True if node is an intersection type node

306

*/

307

function isIntersectionTypeNode(node: Node): node is IntersectionTypeNode;

308

309

/**

310

* Check if node is an array type node

311

* @param node - Node to test

312

* @returns True if node is an array type node

313

*/

314

function isArrayTypeNode(node: Node): node is ArrayTypeNode;

315

316

/**

317

* Check if node is a tuple type node

318

* @param node - Node to test

319

* @returns True if node is a tuple type node

320

*/

321

function isTupleTypeNode(node: Node): node is TupleTypeNode;

322

323

/**

324

* Check if node is a function type node

325

* @param node - Node to test

326

* @returns True if node is a function type node

327

*/

328

function isFunctionTypeNode(node: Node): node is FunctionTypeNode;

329

330

/**

331

* Check if node is a mapped type node

332

* @param node - Node to test

333

* @returns True if node is a mapped type node

334

*/

335

function isMappedTypeNode(node: Node): node is MappedTypeNode;

336

337

/**

338

* Check if node is a conditional type node

339

* @param node - Node to test

340

* @returns True if node is a conditional type node

341

*/

342

function isConditionalTypeNode(node: Node): node is ConditionalTypeNode;

343

344

/**

345

* Check if node is a literal type node

346

* @param node - Node to test

347

* @returns True if node is a literal type node

348

*/

349

function isLiteralTypeNode(node: Node): node is LiteralTypeNode;

350

```

351

352

### Node Navigation

353

354

Functions for traversing and finding AST nodes.

355

356

```typescript { .api }

357

/**

358

* Get the original node before transformations

359

* @param node - Node to get original for

360

* @param nodeTest - Optional test function to validate result

361

* @returns Original node

362

*/

363

function getOriginalNode(node: Node): Node;

364

function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;

365

function getOriginalNode(node: Node | undefined): Node | undefined;

366

function getOriginalNode<T extends Node>(node: Node | undefined, nodeTest: (node: Node | undefined) => node is T): T | undefined;

367

368

/**

369

* Find ancestor node matching predicate

370

* @param node - Starting node

371

* @param callback - Predicate function

372

* @returns Found ancestor or undefined

373

*/

374

function findAncestor<T extends Node>(node: Node | undefined, callback: (element: Node) => element is T): T | undefined;

375

function findAncestor(node: Node | undefined, callback: (element: Node) => boolean): Node | undefined;

376

377

/**

378

* Check if node is from original parse tree

379

* @param node - Node to check

380

* @returns True if from parse tree

381

*/

382

function isParseTreeNode(node: Node): boolean;

383

384

/**

385

* Get original parse tree node

386

* @param node - Node to get parse tree node for

387

* @param nodeTest - Optional test function

388

* @returns Parse tree node

389

*/

390

function getParseTreeNode(node: Node | undefined): Node | undefined;

391

function getParseTreeNode<T extends Node>(node: T | undefined, nodeTest?: (node: Node) => node is T): T | undefined;

392

393

/**

394

* Get all leading trivia for a node

395

* @param node - Node to get trivia for

396

* @param sourceFile - Source file containing the node

397

* @param includeJSDoc - Whether to include JSDoc comments

398

* @returns Array of trivia ranges

399

*/

400

function getLeadingCommentRanges(text: string, pos: number): CommentRange[] | undefined;

401

402

/**

403

* Get all trailing trivia for a node

404

* @param text - Source text

405

* @param pos - Position to start from

406

* @returns Array of trivia ranges

407

*/

408

function getTrailingCommentRanges(text: string, pos: number): CommentRange[] | undefined;

409

```

410

411

**Usage Examples:**

412

413

```typescript

414

import * as ts from "typescript";

415

416

// Find all function declarations in a class

417

function findFunctionsInClass(classNode: ts.ClassDeclaration): ts.FunctionLikeDeclaration[] {

418

const functions: ts.FunctionLikeDeclaration[] = [];

419

420

function visit(node: ts.Node) {

421

if (ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || ts.isArrowFunction(node)) {

422

functions.push(node);

423

}

424

ts.forEachChild(node, visit);

425

}

426

427

visit(classNode);

428

return functions;

429

}

430

431

// Find the containing class for a method

432

function findContainingClass(node: ts.Node): ts.ClassDeclaration | undefined {

433

return ts.findAncestor(node, ts.isClassDeclaration);

434

}

435

```

436

437

### Text and Position Utilities

438

439

Functions for working with text positions and spans.

440

441

```typescript { .api }

442

/**

443

* Get the end position of a text span

444

* @param span - Text span

445

* @returns End position

446

*/

447

function textSpanEnd(span: TextSpan): number;

448

449

/**

450

* Check if a text span contains a position

451

* @param span - Text span to check

452

* @param position - Position to test

453

* @returns True if span contains position

454

*/

455

function textSpanContainsPosition(span: TextSpan, position: number): boolean;

456

457

/**

458

* Check if a text span contains another text span

459

* @param span - Container span

460

* @param other - Contained span

461

* @returns True if span contains other

462

*/

463

function textSpanContainsTextSpan(span: TextSpan, other: TextSpan): boolean;

464

465

/**

466

* Check if two text spans overlap

467

* @param span1 - First span

468

* @param span2 - Second span

469

* @returns True if spans overlap

470

*/

471

function textSpanOverlapsWith(span1: TextSpan, span2: TextSpan): boolean;

472

473

/**

474

* Get intersection of two text spans

475

* @param span1 - First span

476

* @param span2 - Second span

477

* @returns Intersection span or undefined

478

*/

479

function textSpanIntersection(span1: TextSpan, span2: TextSpan): TextSpan | undefined;

480

481

/**

482

* Create a text span

483

* @param start - Start position

484

* @param length - Length of span

485

* @returns Text span object

486

*/

487

function createTextSpan(start: number, length: number): TextSpan;

488

489

/**

490

* Check if a text span is empty (has zero length)

491

* @param span - Text span to check

492

* @returns True if span is empty

493

*/

494

function textSpanIsEmpty(span: TextSpan): boolean;

495

496

/**

497

* Create a text change range

498

* @param span - Text span being changed

499

* @param newLength - New length after change

500

* @returns Text change range object

501

*/

502

function createTextChangeRange(span: TextSpan, newLength: number): TextChangeRange;

503

504

/**

505

* Collapse multiple text change ranges across versions

506

* @param changes - Array of text change ranges

507

* @returns Collapsed text change range

508

*/

509

function collapseTextChangeRangesAcrossMultipleVersions(changes: readonly TextChangeRange[]): TextChangeRange;

510

```

511

512

### Identifier Utilities

513

514

Functions for working with TypeScript identifiers.

515

516

```typescript { .api }

517

/**

518

* Escape leading underscores in identifier for internal use

519

* @param identifier - Identifier text

520

* @returns Escaped identifier

521

*/

522

function escapeLeadingUnderscores(identifier: string): __String;

523

524

/**

525

* Unescape leading underscores for display

526

* @param identifier - Escaped identifier

527

* @returns Unescaped identifier text

528

*/

529

function unescapeLeadingUnderscores(identifier: __String): string;

530

531

/**

532

* Get text content of identifier node

533

* @param identifier - Identifier node

534

* @returns Identifier text

535

*/

536

function idText(identifier: Identifier): string;

537

538

/**

539

* Get display name of symbol

540

* @param symbol - Symbol to get name for

541

* @returns Symbol display name

542

*/

543

function symbolName(symbol: Symbol): string;

544

545

/**

546

* Check if identifier name is reserved word

547

* @param name - Identifier name to check

548

* @param languageVersion - Language version context

549

* @returns True if reserved word

550

*/

551

function isIdentifierANonContextualKeyword(name: string): boolean;

552

553

/**

554

* Check if text is a valid identifier

555

* @param text - Text to validate

556

* @param languageVersion - Language version context

557

* @returns True if valid identifier

558

*/

559

function isValidIdentifier(text: string, languageVersion?: ScriptTarget): boolean;

560

```

561

562

### JSDoc Utilities

563

564

Functions for working with JSDoc comments and annotations.

565

566

```typescript { .api }

567

/**

568

* Get all JSDoc tags for an AST node

569

* @param node - Node to get JSDoc tags for

570

* @returns Array of JSDoc tag nodes

571

*/

572

function getJSDocTags(node: Node): readonly JSDocTag[] | undefined;

573

574

/**

575

* Get JSDoc type annotation for a node

576

* @param node - Node to get JSDoc type for

577

* @returns JSDoc type node

578

*/

579

function getJSDocType(node: Node): TypeNode | undefined;

580

581

/**

582

* Get JSDoc return type annotation

583

* @param node - Node to get return type for

584

* @returns JSDoc return type node

585

*/

586

function getJSDocReturnType(node: Node): TypeNode | undefined;

587

588

/**

589

* Extract text content from JSDoc comment

590

* @param comment - JSDoc comment node

591

* @returns Comment text

592

*/

593

function getTextOfJSDocComment(comment: JSDocComment | undefined): string | undefined;

594

595

/**

596

* Get JSDoc parameter tags for a function

597

* @param node - Function node

598

* @returns Array of JSDoc parameter tags

599

*/

600

function getJSDocParameterTags(node: FunctionLikeDeclaration): readonly JSDocParameterTag[];

601

602

/**

603

* Get JSDoc deprecated tag if present

604

* @param node - Node to check

605

* @returns JSDoc deprecated tag

606

*/

607

function getJSDocDeprecatedTag(node: Node): JSDocDeprecatedTag | undefined;

608

609

/**

610

* Get all JSDoc comments for a node including parents

611

* @param node - Node to get comments for

612

* @param sourceFile - Source file containing node

613

* @returns Array of JSDoc comment nodes

614

*/

615

function getJSDocCommentsAndTags(node: Node, checkParentVariableStatement?: boolean): readonly (JSDoc | JSDocTag)[];

616

```

617

618

**Usage Examples:**

619

620

```typescript

621

import * as ts from "typescript";

622

623

// Extract JSDoc information from functions

624

function analyzeJSDoc(node: ts.FunctionDeclaration) {

625

const jsdocTags = ts.getJSDocTags(node);

626

if (jsdocTags) {

627

for (const tag of jsdocTags) {

628

if (ts.isJSDocParameterTag(tag)) {

629

console.log(`@param ${tag.name?.getText()}: ${tag.comment}`);

630

} else if (ts.isJSDocReturnTag(tag)) {

631

console.log(`@returns: ${tag.comment}`);

632

}

633

}

634

}

635

636

const deprecatedTag = ts.getJSDocDeprecatedTag(node);

637

if (deprecatedTag) {

638

console.log(`Function is deprecated: ${deprecatedTag.comment}`);

639

}

640

}

641

```

642

643

### Syntax Kind Utilities

644

645

Functions for working with syntax kinds and tokens.

646

647

```typescript { .api }

648

/**

649

* Check if syntax kind is a token

650

* @param kind - Syntax kind to test

651

* @returns True if kind is a token

652

*/

653

function isToken(kind: SyntaxKind): boolean;

654

655

/**

656

* Check if syntax kind is a keyword

657

* @param kind - Syntax kind to test

658

* @returns True if kind is a keyword

659

*/

660

function isKeyword(kind: SyntaxKind): boolean;

661

662

/**

663

* Check if syntax kind is a modifier

664

* @param kind - Syntax kind to test

665

* @returns True if kind is a modifier

666

*/

667

function isModifierKind(kind: SyntaxKind): boolean;

668

669

/**

670

* Check if syntax kind is a literal

671

* @param kind - Syntax kind to test

672

* @returns True if kind is a literal

673

*/

674

function isLiteralKind(kind: SyntaxKind): boolean;

675

676

/**

677

* Check if syntax kind is a punctuation token

678

* @param kind - Syntax kind to test

679

* @returns True if kind is punctuation

680

*/

681

function isPunctuation(kind: SyntaxKind): boolean;

682

683

/**

684

* Get token text for a syntax kind

685

* @param kind - Syntax kind

686

* @returns Token text or undefined

687

*/

688

function tokenToString(kind: SyntaxKind): string | undefined;

689

690

/**

691

* Get syntax kind from token text

692

* @param text - Token text

693

* @returns Syntax kind or undefined

694

*/

695

function stringToToken(text: string): SyntaxKind | undefined;

696

```

697

698

### Binding Pattern Utilities

699

700

Functions for working with destructuring patterns.

701

702

```typescript { .api }

703

/**

704

* Check if node is a binding pattern

705

* @param node - Node to test

706

* @returns True if node is binding pattern

707

*/

708

function isBindingPattern(node: Node | undefined): node is BindingPattern;

709

710

/**

711

* Check if node is an object binding pattern

712

* @param node - Node to test

713

* @returns True if node is object binding pattern

714

*/

715

function isObjectBindingPattern(node: Node): node is ObjectBindingPattern;

716

717

/**

718

* Check if node is an array binding pattern

719

* @param node - Node to test

720

* @returns True if node is array binding pattern

721

*/

722

function isArrayBindingPattern(node: Node): node is ArrayBindingPattern;

723

724

/**

725

* Check if node is a binding element

726

* @param node - Node to test

727

* @returns True if node is binding element

728

*/

729

function isBindingElement(node: Node): node is BindingElement;

730

731

/**

732

* Check if binding element is a rest element

733

* @param node - Binding element to test

734

* @returns True if rest element

735

*/

736

function isRestElement(node: Node): node is RestElement;

737

738

/**

739

* Get name from binding pattern element

740

* @param element - Binding element

741

* @returns Element name

742

*/

743

function getNameOfBindingElement(element: BindingElement): string | undefined;

744

```

745

746

## Types

747

748

### Utility Types

749

750

```typescript { .api }

751

type __String = string & { __escapedIdentifier: void };

752

753

interface TextSpan {

754

start: number;

755

length: number;

756

}

757

758

interface TextChangeRange {

759

span: TextSpan;

760

newLength: number;

761

}

762

763

interface CommentRange extends TextRange {

764

hasTrailingNewLine?: boolean;

765

kind: CommentKind;

766

}

767

768

enum CommentKind {

769

SingleLine = 0,

770

MultiLine = 1

771

}

772

773

interface JSDocComment {

774

kind: SyntaxKind.JSDocComment;

775

comment?: string | NodeArray<JSDocText | JSDocLink>;

776

tags?: NodeArray<JSDocTag>;

777

}

778

779

interface JSDocTag extends Node {

780

parent: JSDoc | JSDocTypeLiteral;

781

tagName: Identifier;

782

comment?: string | NodeArray<JSDocText | JSDocLink>;

783

}

784

785

interface JSDocParameterTag extends JSDocTag {

786

kind: SyntaxKind.JSDocParameterTag;

787

name: EntityName;

788

typeExpression?: JSDocTypeExpression;

789

isNameFirst: boolean;

790

isBracketed: boolean;

791

}

792

```

793

794

### Type Guard Result Types

795

796

```typescript { .api }

797

// All type guard functions return type predicates

798

// Example signatures:

799

function isIdentifier(node: Node): node is Identifier;

800

function isFunctionDeclaration(node: Node): node is FunctionDeclaration;

801

function isStringLiteral(node: Node): node is StringLiteral;

802

803

// These enable TypeScript to narrow types automatically

804

const node: ts.Node = getNode();

805

if (ts.isIdentifier(node)) {

806

// node is now typed as ts.Identifier

807

console.log(node.text); // TypeScript knows 'text' property exists

808

}

809

810

if (ts.isFunctionDeclaration(node)) {

811

// node is now typed as ts.FunctionDeclaration

812

console.log(node.name?.text); // TypeScript knows about function properties

813

}

814

```