TypeScript scope analyser for ESLint that provides comprehensive scope analysis capabilities for JavaScript and TypeScript code
npx @tessl/cli install tessl/npm-typescript-eslint--scope-manager@8.42.0The TypeScript Scope Manager is a TypeScript-aware scope analyser for ESLint that provides comprehensive scope analysis capabilities for JavaScript and TypeScript code. It extends ESLint's scope analysis framework to handle TypeScript-specific language features like type parameters, interfaces, enums, namespaces, and advanced type constructs.
npm install @typescript-eslint/scope-managerimport {
analyze,
ScopeManager,
AnalyzeOptions
} from "@typescript-eslint/scope-manager";For additional types and classes:
import {
Reference,
PatternVisitor,
Visitor,
ScopeType,
ReferenceFlag,
DefinitionType,
type PatternVisitorCallback,
type PatternVisitorOptions
} from "@typescript-eslint/scope-manager";For CommonJS:
const { analyze, ScopeManager, Reference, ScopeType } = require("@typescript-eslint/scope-manager");import { analyze } from "@typescript-eslint/scope-manager";
import type { TSESTree } from "@typescript-eslint/types";
import { parse } from "@typescript-eslint/parser";
// Parse TypeScript code to get AST
const code = `
function greet(name: string): string {
const message = 'Hello, ' + name;
return message;
}
`;
const ast = parse(code, {
loc: true,
range: true,
}) as TSESTree.Program;
// Analyze scope
const scopeManager = analyze(ast, {
globalReturn: false,
impliedStrict: false,
jsxPragma: 'React',
lib: ['esnext'],
sourceType: 'module'
});
// Access global scope
console.log(scopeManager.globalScope);
// Get all scopes
console.log(scopeManager.scopes);
// Get variables in each scope
scopeManager.scopes.forEach(scope => {
console.log(`Scope type: ${scope.type}`);
console.log(`Variables: ${scope.variables.map(v => v.name)}`);
});The TypeScript Scope Manager is built around several key components:
analyze() function that processes AST nodes and creates scope treesScopeManager class that maintains scope hierarchies and variable mappingsMain entry point for analyzing AST nodes and generating comprehensive scope information with TypeScript awareness.
function analyze(
tree: TSESTree.Node,
options?: AnalyzeOptions
): ScopeManager;
interface AnalyzeOptions {
childVisitorKeys?: Record<string, string[]>;
globalReturn?: boolean;
impliedStrict?: boolean;
jsxPragma?: string | null;
jsxFragmentName?: string | null;
lib?: Lib[];
sourceType?: SourceType;
/** @deprecated This option never did what it was intended for and will be removed in a future major release. */
emitDecoratorMetadata?: boolean;
}Central scope management system that maintains scope hierarchies, variable mappings, and provides scope navigation and querying capabilities.
class ScopeManager {
currentScope: Scope | null;
declaredVariables: WeakMap<TSESTree.Node, Variable[]>;
globalScope: GlobalScope | null;
nodeToScope: WeakMap<TSESTree.Node, Scope[]>;
scopes: Scope[];
get variables(): Variable[];
getDeclaredVariables(node: TSESTree.Node): Variable[];
acquire(node: TSESTree.Node, inner?: boolean): Scope | null;
isES6(): boolean;
isGlobalReturn(): boolean;
isImpliedStrict(): boolean;
isModule(): boolean;
isStrictModeSupported(): boolean;
}Comprehensive scope type system covering all JavaScript and TypeScript language constructs with specialized behavior for each scope type.
type Scope = BlockScope | CatchScope | ClassScope | ClassFieldInitializerScope
| ClassStaticBlockScope | ConditionalTypeScope | ForScope | FunctionScope
| FunctionExpressionNameScope | FunctionTypeScope | GlobalScope | MappedTypeScope
| ModuleScope | SwitchScope | TSEnumScope | TSModuleScope | TypeScope | WithScope;
enum ScopeType {
block = "block",
catch = "catch",
class = "class",
classFieldInitializer = "class-field-initializer",
classStaticBlock = "class-static-block",
conditionalType = "conditionalType",
for = "for",
function = "function",
functionExpressionName = "function-expression-name",
functionType = "functionType",
global = "global",
mappedType = "mappedType",
module = "module",
switch = "switch",
tsEnum = "tsEnum",
tsModule = "tsModule",
type = "type",
with = "with"
}Variable tracking system with TypeScript-aware type context analysis and comprehensive definition tracking.
class Variable {
readonly name: string;
readonly defs: Definition[];
readonly identifiers: TSESTree.Identifier[];
readonly references: Reference[];
readonly scope: Scope;
get isTypeVariable(): boolean;
get isValueVariable(): boolean;
}
type ScopeVariable = ESLintScopeVariable | Variable;Comprehensive reference tracking system that identifies all identifier occurrences and their usage patterns.
class Reference {
readonly from: Scope;
readonly identifier: TSESTree.Identifier;
readonly resolved: Variable | null;
readonly writeExpr: TSESTree.Node | null;
isWrite(): boolean;
isRead(): boolean;
isReadOnly(): boolean;
isWriteOnly(): boolean;
isReadWrite(): boolean;
}
enum ReferenceFlag {
Read = 0x1,
Write = 0x2,
ReadWrite = 0x3
}Definition tracking system that categorizes how variables are defined and provides detailed context about their declarations.
type Definition = CatchClauseDefinition | ClassNameDefinition
| FunctionNameDefinition | ImplicitGlobalVariableDefinition | ImportBindingDefinition
| ParameterDefinition | TSEnumMemberDefinition | TSEnumNameDefinition
| TSModuleNameDefinition | TypeDefinition | VariableDefinition;
enum DefinitionType {
CatchClause = "CatchClause",
ClassName = "ClassName",
FunctionName = "FunctionName",
ImplicitGlobalVariable = "ImplicitGlobalVariable",
ImportBinding = "ImportBinding",
Parameter = "Parameter",
TSEnumMember = "TSEnumMemberName",
TSEnumName = "TSEnumName",
TSModuleName = "TSModuleName",
Type = "Type",
Variable = "Variable"
}import type { TSESTree, SourceType, Lib } from "@typescript-eslint/types";
interface PatternVisitorOptions {
childVisitorKeys?: Record<string, string[]>;
}
type PatternVisitorCallback = (
pattern: TSESTree.Identifier,
info: {
assignments: (TSESTree.AssignmentExpression | TSESTree.AssignmentPattern)[];
rest: boolean;
topLevel: boolean;
}
) => void;