TypeScript
TypeScript is a statically typed superset of JavaScript developed by Microsoft and first released in 2012. Created by Anders Hejlsberg — who also led the design of C Sharp and Turbo Pascal — TypeScript adds an optional static type system to JavaScript without altering its runtime semantics. TypeScript code compiles to plain JavaScript, meaning it runs anywhere JavaScript runs: in browsers, on servers, and inside embedded runtimes. The type annotations are erased during compilation; they exist only at compile time, where they serve as a machine-checked contract between the programmer and the code.
TypeScript was not created to replace JavaScript but to make large-scale software engineering possible in a language that was designed in ten days for scripting small web pages. Where JavaScript's dynamic typing enables rapid prototyping, TypeScript's static typing enables long-term maintenance. The tension between these two goals — expressivity versus correctness, speed of writing versus speed of reading — is the central drama of TypeScript's design.
Gradual Typing and Structural Types
TypeScript employs gradual typing, a paradigm in which programmers may add type annotations incrementally rather than all at once. A valid JavaScript program is already a valid TypeScript program; the type checker can be dialed from permissive to strict via compiler flags. This incremental adoptability was crucial to TypeScript's success in the JavaScript ecosystem, where legacy codebases and third-party libraries could not be rewritten overnight.
Unlike the nominal type systems of Java or C Sharp, TypeScript uses structural typing: two types are compatible if their shapes match, regardless of their declared names. An object with properties and is assignable to any interface requiring those properties, even if it was never declared as implementing that interface. This aligns TypeScript's type system with JavaScript's runtime duck-typing semantics and avoids the ceremony of explicit interface declarations. But it also introduces subtlety: two types with identical shapes but different intended meanings are treated as interchangeable, a source of both flexibility and confusion.
The Compile-Time Contract
The TypeScript compiler is not merely a translator; it is a lightweight proof assistant for everyday software engineering. It checks that functions are called with arguments of the correct type, that objects contain the properties they claim to contain, and that asynchronous operations are awaited rather than mishandled. These checks happen at compile time, producing no runtime overhead — the compiled JavaScript contains no type information.
This compile-time-only presence means TypeScript cannot guarantee runtime safety. A value fetched from an external API, cast through a type assertion, or passed through a boundary from untyped JavaScript may violate its declared type at runtime. TypeScript's type system is sound only under ideal conditions; in practice, it is a heuristic that catches most errors most of the time, not a formal guarantee like those provided by Coq or Agda. The programmer must still write tests, handle edge cases, and distrust external data. TypeScript does not eliminate the need for defensive programming; it reduces its scope.
TypeScript and the JavaScript Ecosystem
TypeScript's adoption within the JavaScript ecosystem has been near-total among large projects. Major frameworks — Angular, React, Vue, and Svelte — all provide first-class TypeScript support. The npm registry, the world's largest package repository, increasingly ships TypeScript definitions alongside JavaScript implementations. The language has become the de facto standard for professional web development, to the point that modern