38.6 TypeScript in Browser Extensions

Right, so you want to build a browser extension. You’ve chosen TypeScript, which means you’re already smarter than 90% of the people who’ve tried this. You’re also in for a special kind of pain, because the development environment for extensions is a bizarre, anachronistic throwback that the web largely left behind in 2010. It’s not TypeScript’s fault; it’s just that extension APIs were designed for JavaScript the way it was then, and we have to make our modern, type-safe code fit into that old jacket. It’s a tight squeeze, but we can make it work and look good.

38.5 Service Worker Typing with @types/serviceworker

Alright, let’s talk about typing your Service Worker. You’ve written your sw.js, it’s caching assets like a champ, but now you’re staring at your TypeScript code and getting a bunch of angry red squiggles. self is of type Window, and caches doesn’t exist? Madness. This is where @types/serviceworker waltzes in, not as a hero, but as a very competent stagehand who finally turns the lights on so you can see what you’re doing.

38.4 SharedArrayBuffer and Atomics in TypeScript

Right, let’s talk about making your threads play nice with each other. You’ve got your Web Workers humming along, each in their own little isolated universe. That’s great for most tasks, but what if you need them to collaborate on a single, massive chunk of data? Passing that data back and forth with postMessage is like trying to share a single ice cream cone by mailing it to each other—it’s messy, inefficient, and by the time it gets to the third person, it’s just a sticky puddle of regret.

38.3 Web Worker Typed Message Passing

Alright, let’s talk about passing messages to your Web Workers. This is where you, the developer, are most likely to screw up. The browser’s main thread and your worker thread are like two separate islands, shouting messages to each other across a vast ocean. They don’t share memory, which is both Web Workers’ greatest strength (no locking, no race conditions!) and their most annoying constraint. You can’t just hand them a reference to a function or a complex DOM node. The postMessage() API uses the structured clone algorithm to serialize and deserialize whatever you send. It’s surprisingly capable—it handles Maps, Sets, ArrayBuffers, and even circular references! But it has limits. Try sending a function or a DOM element and you’ll get a DataCloneError slapped in your face. Rightly so.

38.2 AssemblyScript: TypeScript-Like Syntax for Wasm

Alright, let’s talk about AssemblyScript. You’ve heard the siren song, haven’t you? “Write WebAssembly using TypeScript syntax! It’s easy!” And to its credit, it mostly is. But before you start porting your entire React app to Wasm expecting a 1000x speedup, let’s have a brutally honest chat about what this is, what it isn’t, and where it absolutely shines. The core idea is devilishly clever: take a strict subset of TypeScript’s syntax, run it through a compiler (asc) that doesn’t target JavaScript but instead targets WebAssembly’s text format (WAT), and then binary-encodes it into a .wasm module. You’re not writing TypeScript that runs on a JavaScript VM; you’re writing a statically-typed language that looks like TypeScript and compiles to a completely different, low-level execution environment. This distinction is everything.

38.1 Typing WebAssembly Modules and Instantiation

Right, so you’ve decided to bring WebAssembly into your TypeScript project. Excellent choice. It’s like strapping a rocket engine to your browser’s JavaScript engine, but now you have the delightful task of telling TypeScript’s notoriously fussy type system to please just relax and trust you with this powerful, untyped beast from the wild west of C++ and Rust. It’s a relationship that requires some… negotiation. The core of the problem is simple: WebAssembly modules are not born with TypeScript type definitions. They arrive as a blob of binary goodness, and all you get from the instantiation process is a nebulous WebAssembly.ResultObject whose instance.exports property is essentially an any-typed free-for-all. Calling a function on that is a leap of faith, and we don’t do that here. We’re professionals. We type things.

— joke —

...