How-toVS Code

TypeScript Language Services and Debugging

Distinguish compiler, language service, source maps, and test runners while debugging a small Node project.

Updated Verified SourceEdit this page

For extension choices and batch installation scope, see language extensions and Profiles.

Compare the language service with the compiler

Open the package and tsconfig root. Run the project type-check script and inspect the active TypeScript service in Language Status. Editor diagnostics, compiler errors, lint, and browser failures are separate evidence. Compiler and language service

Current documentation uses js/ts.* settings. Inspect the installed editor's SDK settings rather than blindly copying older typescript.tsdk examples. TypeScript 7's native compiler/service is a separate compatibility boundary; do not assume a legacy lib path selects it. TS 7 integration, repository compatibility guide

VS Code includes TypeScript editing and JavaScript debugging. Add only your project's formatter, linter, and runner integrations. Use the Oxc lab or the separate Prettier/ESLint alternative.

Use Hover and Signature Help before editing. Parameter-name inlay hints can start at literals; enable References or Implementations CodeLens when useful. Current keys include js/ts.inlayHints.parameterNames.enabled, js/ts.referencesCodeLens.enabled, and js/ts.implementationsCodeLens.enabled. TypeScript editing

Rename with F2, extract expressions through Refactor, and inspect import changes when moving files. TypeScript aliases must also work in the runtime or bundler. React/Next changes need component and framework checks in addition to types. Refactoring

Debug a small compiled Node ESM project

Use a separate learning directory, not the formatter lab's no-emit tsconfig. Run npm init -y and npm install --save-dev --save-exact typescript @types/node, then merge into package.json:

{
    "type": "module",
    "scripts": {
        "build": "tsc -p tsconfig.json",
        "typecheck": "tsc -p tsconfig.json --noEmit"
    }
}

Create tsconfig.json:

{
    "compilerOptions": {
        "target": "ES2022",
        "module": "NodeNext",
        "moduleResolution": "NodeNext",
        "lib": ["ES2022"],
        "types": ["node"],
        "rootDir": "src",
        "outDir": "dist",
        "strict": true,
        "sourceMap": true
    },
    "include": ["src/**/*.ts"]
}

Create src/main.ts:

function total(price: number, quantity: number): number {
    return price * quantity;
}

const result = total(1200, 3);
console.log({ result });

Create .vscode/tasks.json to run the same build script:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "ts: build",
            "type": "shell",
            "command": "npm",
            "args": ["run", "build"],
            "options": { "cwd": "${workspaceFolder}" },
            "problemMatcher": ["$tsc"],
            "group": "build"
        }
    ]
}

Create .vscode/launch.json. It launches emitted JavaScript and maps back to TypeScript:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "name": "TS: compiled Node program",
            "request": "launch",
            "program": "${workspaceFolder}/dist/main.js",
            "cwd": "${workspaceFolder}",
            "preLaunchTask": "ts: build",
            "outFiles": ["${workspaceFolder}/dist/**/*.js"],
            "sourceMaps": true,
            "skipFiles": ["<node_internals>/**"]
        }
    ]
}

Break on return and press F5. Inspect price 1200, quantity 3, and result 3600. For an unbound breakpoint, check emitted JS/maps, original source paths, the process, and exact preLaunchTask label. TypeScript debugging

Distinguish browser, Node, and Bun processes

Browser debugging needs the development URL and matching webRoot. Node servers can start in JavaScript Debug Terminal or use attach. In SSR applications, place separate breakpoints in server functions and browser event handlers. Node debugging

Use Bun's documented debugging path for Bun processes instead of assuming the Node inspector contract. Bun debugger

Run the actual test runner. Vitest, Jest, Bun test, and Playwright are different systems. Unit-test discovery does not validate a production browser flow.

Diagnose discrepancies

SymptomInspect
Editor-only type errorsActive service version and owning tsconfig
One package lacks lintActual cwd/config and workingDirectories
Typed lint cannot read a fileProject service and include scope
Alias fails at runtimeRuntime/bundler resolution and package exports
Slow savesFormatter and type-aware lint timings separately
Browser-only failuresExecution side, source maps, and network

Select explicit package roots if automatic working-directory detection is wrong. Enable typed lint for concrete rules and a deliberate scope. ESLint extension, typed linting

The Train To Code walkthrough demonstrates local compilation and debugging. Use current SDK settings rather than copying historical setup details.