TypeScript brings static typing to JavaScript, but debugging TypeScript in Firefox DevTools requires some extra knowledge. Source maps are the key — they let Firefox show your original .ts files even though the browser runs compiled .js. This guide covers setup, debugging patterns, and TypeScript-specific tooling.

How Source Maps Work

When TypeScript compiles to JavaScript, it can generate a .map file:

myfile.ts → myfile.js + myfile.js.map 

The .map file tells Firefox DevTools: "line 42 in myfile.js corresponds to line 38 in myfile.ts."

Firefox then shows your original TypeScript in the debugger, not the compiled output.

tsconfig.json for Debugging

{ "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", "strict": true, "sourceMap": true, "inlineSources": true, "outDir": "./dist", "rootDir": "./src" } } 

Key flags:

  • "sourceMap": true — generates .map files alongside .js
  • "inlineSources": true — embeds source content in the map (works even if original files aren't served)
  • "inlineSourceMap": true — embeds the map inside the JS file (one file, easier for dev)

Setting Up Firefox DevTools for TypeScript

  1. Open DevTools → Settings (F1)
  2. Ensure "Enable Source Maps" is checked (it is by default)
  3. Open the Debugger tab
  4. Your .ts files appear in the file tree under the source map group
// src/counter.ts interface Counter { count: number; increment(): void; reset(): void; } function createCounter(initial = 0): Counter { let count = initial; return { get count() { return count; }, increment() { count++; }, reset() { count = initial; } }; } const counter = createCounter(10); counter.increment(); // Set breakpoint here in DevTools console.log(counter.count); // 11 

Set a breakpoint on counter.increment() — Firefox pauses and shows you counter.ts, not the compiled output.

TypeScript Type Errors in the Console

TypeScript errors are compile-time, not runtime. But type errors can manifest as runtime issues:

// TypeScript (compile error, but compiles with --noEmitOnError false): function greet(name: string): string { return "Hello, " + name; } // If called with wrong type at runtime: greet(42 as any); // No TS error but you passed a number 

Firefox DevTools console shows the runtime result ("Hello, 42"), not a type error. TypeScript's job is done at compile time.

For runtime type checking, use:

function greet(name: unknown): string { if (typeof name !== 'string') { throw new TypeError(`Expected string, got ${typeof name}`); } return "Hello, " + name; } 

Now Firefox shows TypeError: Expected string, got number with the full stack trace.

Inspecting TypeScript Types in the Console

The console doesn't know TypeScript types at runtime — types are erased during compilation. But you can use typeof and structured inspection:

// In TypeScript source interface User { id: number; name: string; roles: string[]; } const user: User = { id: 1, name: 'Alice', roles: ['admin', 'user'] }; window.__debugUser = user; // Expose for console inspection 

In Firefox console:

// Types are gone, but structure remains typeof __debugUser // "object" Object.keys(__debugUser) // ["id", "name", "roles"] __debugUser instanceof Object // true 

TypeScript with Firefox WebExtensions

Firefox extensions benefit from TypeScript — catch errors before publishing to AMO:

npm install --save-dev typescript @types/firefox-webext-browser 

tsconfig.json for Firefox extension:

{ "compilerOptions": { "target": "ES2017", "lib": ["ES2017"], "strict": true, "sourceMap": true, "types": ["firefox-webext-browser"] } } 
// background.ts browser.tabs.onUpdated.addListener((tabId, changeInfo, tab) => { // Types are inferred! tabId: number, changeInfo: browser.tabs.TabChangeInfo, etc. if (changeInfo.status === 'complete' && tab.url) { console.log('Tab loaded:', tab.url); } }); // TypeScript catches this at compile time: browser.tabs.query({ actve: true }); // Error: 'actve' is not assignable 

Debugging TypeScript with Vite

Vite is the most common bundler for TypeScript web apps, and it works well with Firefox:

// vite.config.ts import { defineConfig } from 'vite'; export default defineConfig({ build: { sourcemap: true, // Enable source maps in production build }, }); 

In development, Vite serves source maps automatically. Firefox DevTools shows your .ts files directly.

TypeScript Declaration Files

When using third-party libraries without TypeScript support, you can add types:

// types/mylib.d.ts declare module 'mylib' { export function doThing(value: string): number; export const VERSION: string; } 

These don't affect the compiled output, but TypeScript (and your IDE) will understand the types.

Practical TypeScript Patterns for Firefox Apps

// Custom error types class NetworkError extends Error { constructor( message: string, public readonly status: number, public readonly url: string ) { super(message); this.name = 'NetworkError'; } } // Type-safe event emitter type EventMap = { 'data': { id: number; value: string }; 'error': Error; 'close': void; }; class TypedEmitter<T extends Record<string, unknown>> { private listeners = new Map<keyof T, Set<(data: T[keyof T]) => void>>(); on<K extends keyof T>(event: K, listener: (data: T[K]) => void): void { if (!this.listeners.has(event)) this.listeners.set(event, new Set()); this.listeners.get(event)!.add(listener as any); } emit<K extends keyof T>(event: K, data: T[K]): void { this.listeners.get(event)?.forEach(fn => fn(data)); } } const emitter = new TypedEmitter<EventMap>(); emitter.on('data', ({ id, value }) => console.log(id, value)); // fully typed 

TypeScript + Firefox DevTools: Performance

TypeScript compilation adds a build step. For fastest development iteration:

  1. Use tsc --watch or your bundler's watch mode
  2. Enable Firefox DevTools "Enable browser toolbox" for extension debugging
  3. Use about:debugging#/runtime/this-firefox to load and reload extensions without restarting Firefox
  4. Check the Browser Console (Ctrl+Shift+J) for extension background script errors

TypeScript's compile step catches a whole class of bugs before they reach the browser — pair it with Firefox DevTools for a solid development workflow.