TypeScript / JavaScript
The TypeScript extractor covers both languages. One grammar handles.ts/.tsx, another handles .js/.jsx/.mjs/.cjs. Both map onto the same canonical concepts.
What it detects
- Functions: declarations, expressions, and arrow functions all become
Function - Methods:
method_definitionbecomesMethod - Classes: declarations and expressions become
Class - Interfaces:
interface_declarationbecomesInterface - Types:
type_alias_declarationbecomesTypeDef - Enums:
enum_declarationbecomesEnum - Imports:
import_statementbecomesImport, withNamedImports/NamespaceImportchildren - Exports:
export_statementandexport_defaultbecomeExport - Variables:
variable_declaration(var) andlexical_declaration(let/const) becomeVariable, labeled with the declarator name - JSX: elements, attributes, and expressions are their own concepts
- Control flow: if / for / while / switch / try / return / throw
- Literals and expressions: strings, numbers, templates, regex, booleans, objects, arrays, calls, member access, operators, await / yield
Node type mapping
Node types without a mapping keep their raw tree-sitter type name.
Labels. Most declarations are named via the
name field, read straight off the tree-sitter cursor. variable_declaration and lexical_declaration are the exceptions. Their names live on a variable_declarator child, so they go through extractLabel.
Example: a TypeScript refactor
RenamecomputeTotal to calculateTotalAmount, add a discount parameter, and move the function to another file:
utils.ts losing a function and math.ts gaining one, with the whole body rewritten. The semantic diff reports one function that moved, was renamed, and gained a parameter.
Known limitations
- Multi-declarator variables:
const a = 1, b = 2labels theVariablewith the first declarator’s name only. - Interface members are distinct concepts:
property_signature,call_signature, andmethod_signatureare separate concepts, not a unified “member”. - JSX text is a flat node:
jsx_textcollapses contiguous text, so inline formatting changes inside JSX text can read as a single update. - No type-flow inference: the extractor does not distinguish a value used as a type from a type used as a value.
- Unmapped node types pass through: anything outside the map keeps its raw tree-sitter type name.