ProgramGuru

Variable Scope

Learn Variable Scope

Scope determines where a variable can be accessed, while shadowing lets a nested block use a distinct binding with the same name.

In this lesson, you will study the rule, run a complete TypeScript example, explain its output, and test a small change.

What you’ll learn

  • Explain the main rule behind variable scope.
  • Predict the result of the complete runnable TypeScript example.
  • Recognize one common mistake and correct it.

Understand the concept

let and const are block-scoped. A name declared inside { ... } is not available outside that block. The nearest in-scope declaration wins, so a nested variable can shadow an outer variable. var has function scope and different behavior; prefer modern bindings.

See the concept visually

Use the diagram to locate the checks, values or branches involved in the example.

Variable Scope: illustrated flowOuter block: label; Inner block: label; Inner read → inner; Outer read → outer1Outer block: label2Inner block: label3Inner read → inner4Outer read → outerCompare the cases; they do not all necessarily execute.
Variable Scope: illustrated flow. Outer block: label; Inner block: label; Inner read → inner; Outer read → outer.

Run a complete TypeScript example

Save this code as main.ts or paste it into the TypeScript Playground. The example uses fixed values so it runs without prompting for input.

TypeScript code

const label: string = "outer";
 if (true) {
   const label: string = "inner";
   console.log(label);
 }
 console.log(label);

Verified output

inner
outer

How to run locally: npx tsc --strict --target es2022 --module commonjs main.ts, then node main.js. When using a project configuration, run the matching project build instead.

Trace the execution

Inside the block, the inner label shadows the outer one, so inner prints. Once execution leaves the block, the outer label is visible again and outer prints.

Predict the output before you run the sample. Compare each line with the source expression that produced it, and distinguish the type checker’s work from what happens in JavaScript at runtime.

Common mistakes and how to avoid them

Do not assume a variable declared with let inside a branch is accessible after the closing brace. Avoid unnecessary shadowing where it makes code confusing.

Debugging habit: when a change is rejected, read the exact compiler diagnostic and inspect the operand types. When it compiles but behaves unexpectedly, follow the values through the JavaScript expressions.

Practice it yourself

Rename the inner variable to message and print both names inside the block. Then declare a variable in a for loop and try to access it afterwards.

Challenge: write down your prediction first, run the changed source, and explain any difference. Return to the verified version before continuing.

Check your understanding

Which label is used by the final console.log?
Choose one answer. You can try again.

Answer and explanation

The outer label.

The inner binding exists only in its block; the outer binding remains available.

Review the key idea

Variable Scope: let and const are block-scoped.

The inner binding exists only in its block; the outer binding remains available.

Before continuing, be able to explain what is checked before execution and what actually changes at runtime in the example above.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Introduction to Functions →