Utility functions for working with TypeScript's Abstract Syntax Tree (AST) and type system
npx @tessl/cli install tessl/npm-tsutils@3.21.0TSUtils provides comprehensive utility functions and type guard functions for working with TypeScript's Abstract Syntax Tree (AST) and type system. It offers backwards compatibility with TypeScript 2.8.0+ and includes modular imports for selective usage - users can import only type guards, only utilities, or both. The library features version-specific type guard functions to maintain compatibility across different TypeScript versions, with specialized functions for traversing AST nodes, analyzing types, working with comments and tokens, and performing type-safe operations on TypeScript compiler APIs.
npm install tsutilstypescript >=2.8.0import * as utils from "tsutils";
// Access both type guards and utilities
utils.isIdentifier(node);
utils.getLineRanges(sourceFile);For selective imports:
// Only type guards
import { isIdentifier, isCallExpression } from "tsutils/typeguard";
// Only utilities
import { forEachComment, forEachToken } from "tsutils/util";
// Version-specific type guards
import { isIdentifier } from "tsutils/typeguard/2.8";CommonJS:
const utils = require("tsutils");
const { isIdentifier, forEachToken } = require("tsutils");import * as ts from "typescript";
import { isIdentifier, isCallExpression, forEachToken, getLineRanges } from "tsutils";
// Type guard usage
function analyzeNode(node: ts.Node) {
if (isIdentifier(node)) {
// node is now typed as ts.Identifier
console.log("Identifier:", node.text);
}
if (isCallExpression(node)) {
// node is now typed as ts.CallExpression
console.log("Function call:", node.expression);
}
}
// Utility usage
function analyzeSourceFile(sourceFile: ts.SourceFile) {
// Iterate through all tokens
forEachToken(sourceFile, (token) => {
console.log("Token:", ts.SyntaxKind[token.kind]);
});
// Get line information
const lines = getLineRanges(sourceFile);
console.log("Total lines:", lines.length);
}TSUtils is organized into two main functional areas:
Type guard functions for TypeScript AST nodes using ts.SyntaxKind enumeration. Provides 181 functions covering all TypeScript syntax constructs including declarations, expressions, statements, literals, and JSX elements.
function isIdentifier(node: ts.Node): node is ts.Identifier;
function isCallExpression(node: ts.Node): node is ts.CallExpression;
function isIfStatement(node: ts.Node): node is ts.IfStatement;
function isStringLiteral(node: ts.Node): node is ts.StringLiteral;
function isFunctionDeclaration(node: ts.Node): node is ts.FunctionDeclaration;Type guard functions for TypeScript's type system using ts.TypeFlags. Provides 18 functions for checking union types, intersection types, literal types, object types, and other type system constructs.
function isUnionType(type: ts.Type): type is ts.UnionType;
function isIntersectionType(type: ts.Type): type is ts.IntersectionType;
function isLiteralType(type: ts.Type): type is ts.LiteralType;
function isObjectType(type: ts.Type): type is ts.ObjectType;
function isTypeReference(type: ts.Type): type is ts.TypeReference;Comprehensive utilities for navigating, analyzing, and manipulating TypeScript AST nodes. Includes token iteration, comment processing, position mapping, and node relationship traversal.
function forEachToken(node: ts.Node, cb: (node: ts.Node) => void, sourceFile?: ts.SourceFile): void;
function forEachComment(node: ts.Node, cb: ForEachCommentCallback, sourceFile?: ts.SourceFile): void;
function getPreviousToken(node: ts.Node, sourceFile?: ts.SourceFile): ts.Node | undefined;
function getNextToken(node: ts.Node, sourceFile?: ts.SourceFile): ts.Node | undefined;
function getAstNodeAtPosition(node: ts.Node, pos: number): ts.Node | undefined;Advanced analysis utilities for scope boundaries, variable declarations, control flow, import/export analysis, and compiler option checking.
function isScopeBoundary(node: ts.Node): ScopeBoundary;
function getVariableDeclarationKind(declarationList: ts.VariableDeclarationList): VariableDeclarationKind;
function hasModifier(modifiers: ts.ModifiersArray | undefined, ...kinds: Array<ts.Modifier['kind']>): boolean;
function isParameterProperty(node: ts.ParameterDeclaration): boolean;
function findImports(sourceFile: ts.SourceFile, kinds: ImportKind): Array<ts.StringLiteral | ts.NoSubstitutionTemplateLiteral>;Text processing utilities for source code analysis including line range calculation, identifier validation, comment extraction, and position-based operations.
function getLineRanges(sourceFile: ts.SourceFile): LineRange[];
function isValidIdentifier(text: string, languageVersion?: ts.ScriptTarget): boolean;
function commentText(sourceText: string, comment: ts.CommentRange): string;
function isPositionInComment(sourceFile: ts.SourceFile, pos: number, parent?: ts.Node): boolean;
function isSameLine(sourceFile: ts.SourceFile, pos1: number, pos2: number): boolean;Text Processing and Validation
Specialized utilities for analyzing variable declarations, usage patterns, and scope analysis. Provides detailed information about variable domains, export status, and usage locations.
function collectVariableUsage(sourceFile: ts.SourceFile): Map<ts.Identifier, VariableInfo>;
function getUsageDomain(node: ts.Identifier): UsageDomain | undefined;
function getDeclarationDomain(node: ts.Identifier): DeclarationDomain | undefined;
interface VariableInfo {
domain: DeclarationDomain;
exported: boolean;
uses: VariableUse[];
inGlobalScope: boolean;
declarations: ts.Identifier[];
}Advanced type system analysis including type assignability checking, property analysis, class type inspection, and type manipulation utilities.
function isTypeAssignableToNumber(checker: ts.TypeChecker, type: ts.Type): boolean;
function isTypeAssignableToString(checker: ts.TypeChecker, type: ts.Type): boolean;
function unionTypeParts(type: ts.Type): ts.Type[];
function getPropertyOfType(type: ts.Type, name: ts.__String): ts.Symbol | undefined;
function getSymbolOfClassLikeDeclaration(node: ts.ClassLikeDeclaration, checker: ts.TypeChecker): ts.Symbol;Control flow analysis utilities for determining statement reachability, analyzing function signatures, and identifying control flow termination points.
function endsControlFlow(statement: ts.Statement | ts.BlockLike, checker?: ts.TypeChecker): boolean;
function getControlFlowEnd(statement: ts.Statement | ts.BlockLike, checker?: ts.TypeChecker): ControlFlowEnd;
function callExpressionAffectsControlFlow(node: ts.CallExpression, checker: ts.TypeChecker): SignatureEffect | undefined;enum VariableDeclarationKind {
Var,
Let,
Const
}
enum ScopeBoundary {
None = 0,
Function = 1,
Block = 2,
Type = 4,
ConditionalType = 8
}
enum AccessKind {
None = 0,
Read = 1,
Write = 2,
Delete = 4,
ReadWrite = Read | Write,
Modification = Write | Delete
}
enum DeclarationDomain {
Namespace = 1,
Type = 2,
Value = 4,
Import = 8,
Any = Namespace | Type | Value
}
enum UsageDomain {
Namespace = 1,
Type = 2,
Value = 4,
ValueOrNamespace = Value | Namespace,
Any = Namespace | Type | Value,
TypeQuery = 8
}type ForEachTokenCallback = (fullText: string, kind: ts.SyntaxKind, range: ts.TextRange, parent: ts.Node) => void;
type ForEachCommentCallback = (fullText: string, comment: ts.CommentRange) => void;interface LineRange extends ts.TextRange {
contentLength: number;
}
interface NodeWrap {
node: ts.Node;
kind: ts.SyntaxKind;
children: NodeWrap[];
next?: NodeWrap;
skip?: NodeWrap;
parent?: NodeWrap;
}