Skip to main content

TypeScript Support

Skylos provides analysis capabilities for TypeScript (.ts, .tsx) and JavaScript (.js, .jsx) files using tree-sitter parsing.

Features​

TypeScript analysis includes:

  • Dead code detection: Unused functions, classes, interfaces, enums, type aliases, variables, methods, and imports
  • Security scanning: eval(), unsafe innerHTML, document.write(), new Function(), outerHTML, string-based timers, command injection, webhook signature verification
  • Quality analysis: Cyclomatic complexity, nesting depth, function length, and parameter count

How It Works​

Skylos uses tree-sitter with the TypeScript grammar to parse files into a syntax tree. This enables accurate analysis without requiring a full TypeScript compiler setup.

Parsing Pipeline​

  1. Read source file as bytes
  2. Parse with tree-sitter TypeScript grammar
  3. Query for definitions (functions, classes, interfaces, enums, type aliases, methods, variables, imports)
  4. Query for references (calls, property accesses, type references, decorators, exports, inheritance)
  5. Cross-reference to find unused definitions

Dead Code Detection​

Supported Definitions​

TypeDetection Pattern
Functionsfunction foo() {}
Arrow functionsconst foo = () => {}
Classesclass Foo {}
Interfacesinterface Foo {}
Enumsenum Foo {}
Type aliasestype Foo = ...
Methodsclass { method() {} }
Top-level variablesconst foo = value
Importsimport { foo } from '...'

Export Awareness​

Exported definitions are treated differently:

// Not flagged - exported
export function publicApi() {}

// Flagged if not called internally
function internalHelper() {}

Lifecycle Method Exclusions​

Framework lifecycle methods are automatically excluded from dead code detection:

  • React: constructor, render, componentDidMount, componentWillUnmount, componentDidUpdate, shouldComponentUpdate, getDerivedStateFromProps, getSnapshotBeforeUpdate
  • Angular: ngOnInit, ngOnDestroy, ngOnChanges, ngAfterViewInit
  • Web Components: connectedCallback, disconnectedCallback, attributeChangedCallback

Reference Tracking​

Skylos tracks references across many usage patterns:

  • Function calls and new expressions
  • Property accesses and member expressions
  • Callback arguments, return values, and spread elements
  • Array storage and object shorthand properties
  • Type annotations and type references
  • Decorator usage (decorated classes are not flagged)
  • Export specifiers and extends clauses

Security Rules​

SKY-D501: eval()​

Detects use of eval(), which can execute arbitrary code.

// Flagged (CRITICAL)
eval(userInput);

SKY-D502: innerHTML​

Detects unsafe innerHTML assignments that could enable XSS.

// Flagged (HIGH)
element.innerHTML = userContent;

SKY-D503: document.write()​

Detects document.write() calls that can lead to XSS vulnerabilities.

// Flagged (HIGH)
document.write(data);

SKY-D504: new Function()​

Detects new Function() constructor which is equivalent to eval().

// Flagged (CRITICAL)
const fn = new Function('return ' + userInput);

SKY-D505: String-based Timers​

Detects setTimeout() and setInterval() with string arguments, which are equivalent to eval().

// Flagged (HIGH)
setTimeout("alert('xss')", 1000);
setInterval("doStuff()", 500);

// Not flagged - function reference
setTimeout(() => alert('ok'), 1000);

SKY-D506: child_process.exec()​

Detects .exec() calls that may indicate command injection. Safe objects like regex, db, stmt, and cursor are automatically excluded.

SKY-D282: Unverified webhook handler​

Detects Next.js, Express, and similar webhook handlers that process inbound provider events without obvious signature verification.

// Flagged (HIGH)
export async function POST(req: Request) {
const event = await req.json();
await grantCredits(event.data.object.customer);
}

// Not flagged - provider signature is verified before trusting the event
export async function POST(req: Request) {
const body = await req.text();
const sig = req.headers.get("stripe-signature");
const event = stripe.webhooks.constructEvent(body, sig, process.env.STRIPE_WEBHOOK_SECRET!);
}

The rule requires webhook/provider evidence, POST handling, and body usage, then suppresses when strong verification evidence such as constructEvent, createHmac, or crypto.timingSafeEqual is present.

// Flagged (HIGH)
child_process.exec(userCommand);

// Not flagged - regex exec is safe
const match = pattern.exec(input);

SKY-D507: outerHTML​

Detects unsafe outerHTML assignments that could enable XSS.

// Flagged (HIGH)
element.outerHTML = userContent;

Quality Rules​

SKY-Q601: Function Complexity​

Measures cyclomatic complexity for TypeScript functions.

Complexity nodes:

  • if_statement
  • for_statement
  • while_statement
  • switch_case
  • catch_clause
  • ternary_expression
// Complexity: 4
function process(data: Data) {
if (data.valid) { // +1
for (const item of data.items) { // +1
if (item.active) { // +1
handle(item);
}
}
}
}

SKY-Q602: Nesting Depth​

Flags functions with deeply nested control flow.

Nesting nodes:

  • if_statement
  • for_statement, for_in_statement
  • while_statement, do_statement
  • switch_statement
  • try_statement
// Nesting depth: 3 (flagged if limit is 4)
function deep() {
if (a) { // depth 1
for (const x of items) { // depth 2
if (x.ok) { // depth 3
handle(x);
}
}
}
}

SKY-Q603: Function Length​

Flags functions that exceed the maximum line count.

// Flagged if > 50 lines (default)
function longFunction() {
// ... 60 lines of code
}

SKY-Q604: Parameter Count​

Flags functions with too many parameters.

// Flagged if > 5 parameters (default)
function configure(a: string, b: number, c: boolean, d: object, e: string[], f: Map<string, any>) {
// ...
}

Configuration​

Override TypeScript thresholds separately from Python:

[tool.skylos.languages.typescript]
complexity = 15 # Higher threshold for TS

Running Analysis​

Skylos automatically detects TypeScript files in the scan path:

# Scans Python, TypeScript, and JavaScript
skylos ./src --danger --quality

File Extensions​

Supported extensions:

  • .ts - TypeScript
  • .tsx - TypeScript with JSX
  • .js - JavaScript
  • .jsx - JavaScript with JSX

Output Example​

──────────────────── Unreachable Functions ────────────────────
# Name Location
1 unusedHelper src/utils.ts:45
2 deprecatedFunc src/legacy.ts:12
3 OldInterface src/types.ts:8

───────────────────── Security Issues ─────────────────────────
# Rule Severity Message Location
1 SKY-D501 Critical Use of eval() detected src/dynamic.ts:23
2 SKY-D502 High Unsafe innerHTML assignment src/render.tsx:67
3 SKY-D503 High document.write() can lead to XSS src/legacy.ts:12
4 SKY-D504 Critical new Function() is equivalent to eval src/exec.ts:5
5 SKY-D506 High child_process.exec() command inject src/run.ts:41

────────────────────── Quality Issues ─────────────────────────
# Rule Severity Message Location
1 SKY-Q601 Medium Function 'processData' complexity 18 src/processor.ts:30
2 SKY-Q602 Medium Function 'handle' nesting depth 6 src/handler.ts:15
3 SKY-Q603 Low Function 'init' is 85 lines long src/setup.ts:10
4 SKY-Q604 Low Function 'configure' has 8 params src/config.ts:22

Monorepo And Import Resolution​

Skylos discovers TypeScript and JavaScript workspaces from:

  • package.json workspaces arrays and { "packages": [...] } objects
  • pnpm-workspace.yaml packages entries
  • lerna.json packages entries
  • rush.json projects[].projectFolder entries
  • root tsconfig.json project references

Declared workspace packages are used for package-name import resolution. Skylos also resolves tsconfig baseUrl/paths, extends, package self-imports, package exports, package imports, main, module, and common source entrypoints such as src/index.ts, src/index.tsx, index.js, and index.jsx.

Workspace inventory is included in scan metadata so cloud uploads and JSON consumers can tell which packages were discovered, which files declared them, and whether undeclared package folders were found.

Limitations​

Not Supported​

  • Type checking: Skylos doesn't validate TypeScript types
  • Full Node resolver emulation: resolution covers common source and package metadata patterns, but not every conditional export or package-manager-specific edge case
  • JSDoc: Documentation comments are not analyzed

Workarounds​

For React components that appear unused:

// Components exported from index are often used externally
export { MyComponent } from './MyComponent'; // Not flagged

For dynamic patterns:

// noqa: skylos
const handler = handlers[eventType];

Dependencies​

TypeScript support requires:

tree-sitter>=0.25.2
tree-sitter-typescript>=0.23.2

These are installed automatically with Skylos:

pip install skylos

Integration with Python Projects​

Skylos can analyze mixed-language projects:

my-project/
β”œβ”€β”€ backend/ # Python - fully analyzed
β”‚ β”œβ”€β”€ api/
β”‚ └── models/
β”œβ”€β”€ frontend/ # TypeScript - analyzed
β”‚ β”œβ”€β”€ src/
β”‚ └── components/
└── pyproject.toml
# Analyze everything
skylos . --danger --quality

# Analyze only frontend
skylos ./frontend --quality