Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.refactron.dev/llms.txt

Use this file to discover all available pages before exploring further.

Transform ID: var_to_const_let Language: TypeScript

What it does

For every var declaration in the file, decide per binding:
  • const if the binding is never reassigned after initialization.
  • let if the binding is reassigned at least once.
Each binding is judged independently — multiple var statements in one file may map to a mix of const and let.

Detector pattern

The detector at src/analyze/detectors/typescript/var-declarations.ts collects all VariableStatement nodes with the var keyword via ts-morph and then walks the surrounding scope to count reassignments per binding name.

Preconditions

  1. No binding in the file is referenced before its declaration (relying on var hoisting). If hoisting is used anywhere, the entire file is skipped — the transform refuses to break working hoisted code.
  2. No var is declared inside a with statement (legacy scope rules differ from let/const).
  3. The file contains at least one var statement.

Before / after

// Legacy var-style declarations.
export function sumTo(n) {
  var counter = 0;
  for (var i = 1; i <= n; i++) {
    counter = counter + i;
  }
  return counter;
}

export function makeGreeting(name) {
  var greeting = 'hi';
  return greeting + ', ' + name;
}

Edge cases handled

  • Mixed const/let outcomes inside a single file based on each binding’s mutability.
  • Multiple independent vars in one file (var a = 1; var b = 2; b = b + 1;const a = 1; let b = 2; b = b + 1;).
  • for (var i = 0; ...) becomes for (let i = 0; ...) when i is mutated by the loop step.

Edge cases NOT handled (skip via precondition)

  • File relies on hoisting (e.g. console.log(x); var x = 1;).
  • var declared inside a with block.
  • .cjs files (handled by commonjs_to_esm when relevant; var inside CommonJS modules has different historical patterns).