Advanced TypeScript — Mission
Sections
Reading settings
No voice for this language in this browser.
More voices
Code and English terms
Off: the page’s voice reads everything, with no pause between two voices.
No voice for this language in this browser.
More voices
More voices: Microsoft Edge has natural online voices, and Windows (Settings › Time & language › Speech), macOS and Android install others.
Why I’m learning this
Section titled “Why I’m learning this”After the TypeScript for C#/Java developers course, I can read and write strict TypeScript. What I can’t do yet is read the types that libraries are made of: a Zod schema whose type is computed from its definition, a router that knows the parameters of a path from the path string, an event emitter that checks the name of an event and the shape of its payload. Those types are programs, run by the checker, and they have their own control flow, their own recursion and their own limits.
The other half is what happens around the checker: what a type promises when the data comes from a socket, how a large project is compiled, what the declaration files of a package say, and what changed when the compiler was rewritten in Go. This course takes each of those apart, on real code: the front end of Guitar Alchemist (GA) and the SignalR hub it talks to.
Who this course is for
Section titled “Who this course is for”You write TypeScript with strict on, and you are comfortable with unions, narrowing, generics, keyof and a first mapped type, which are lessons 2 to 4 of the base course. You know C# or Java well, since the comparisons are with them. You don’t need to have written a conditional type or a declaration file.
The base course introduces each tool where a C# or Java developer first needs it. This course assumes that you use them, and looks at how the checker evaluates them, where they stop working, and how libraries are built on top of them. Components, JSX and the DOM belong to the React (Vite) course.
Advanced TypeScript in one table
Section titled “Advanced TypeScript in one table”| C# | Java | TypeScript | |
|---|---|---|---|
| Computing a type from another | source generators, T4 | annotation processors | conditional, mapped and template literal types, run by the checker |
| A string that carries a type | no: a typed key object | no: a Class<T> token |
a literal type: 'NodeChanged' is a type |
| Declared variance | in/out on interfaces and delegates, checked |
? extends, ? super at the use site |
measured from the structure; in/out optional, partly checked |
| A nominal wrapper | readonly record struct, no allocation |
a record, an object | a brand, erased: zero cost, zero run-time check |
| Checking data from outside | the types exist at run time: System.Text.Json can check them |
Jackson, Bean Validation | a schema library, whose type is derived from the schema |
| Expected failures | exceptions, or a result type | checked exceptions | a result union, and exceptions for bugs |
The data
Section titled “The data”The lessons use GuitarAlchemist/ga at commit 32f143c: the component library ReactComponents/ga-react-components, in particular its Prime Radiant governance view, and the C# hub that feeds it, Apps/ga-server/GaApi/Hubs/GovernanceHub.cs. The lessons reduce the lines they quote to files that run on their own and say where each one comes from. The checker’s own source is quoted from microsoft/typescript-go at the tag typescript/v7.0.2 (commit 2bd066d). What the lessons found in GA is in the journal.
By the end of this course, I will be able to
Section titled “By the end of this course, I will be able to”- write and test types that compute other types: conditional types,
infer, mapped types with key remapping, template literal types, recursive types, and know the limits at which the checker gives up; - predict the variance that
tscmeasures, spot where it is unsound, and control inference withsatisfies,consttype parameters andNoInfer; - model a domain so that the mistakes are compile errors: brands, opaque types, unions without impossible states, typed state machines;
- check data at the border of the program with a schema library, and return typed errors instead of throwing them;
- write and publish declaration files, configure module resolution for Node.js and bundlers, and publish a package for ESM and CommonJS;
- compile a large project with project references, measure where the checker spends its time, and move a project to TypeScript 7;
- use standard decorators, the compiler API and typed lint rules, and test types in CI;
- read how typed libraries are built: builders, fluent APIs, typed routes and query builders.
Outline
Section titled “Outline”| # | Lesson | You already know |
|---|---|---|
| 1 | Type-level programming | generics, overload resolution, source generators |
| 2 | Variance and assignability | IEnumerable<out T>, wildcards, type inference |
| 3 | Modeling with types | records, value objects, sealed hierarchies, the state pattern |
| 4 | Runtime borders: schemas and typed errors | System.Text.Json, Jackson, Bean Validation, exceptions |
| 5 | Declaration files: .d.ts, declare module, module and global augmentation, typing a JavaScript library, DefinitelyTyped |
reference assemblies, XML documentation files |
| 6 | Modules and resolution: moduleResolution nodenext and bundler, exports and imports, dual ESM/CommonJS packages, isolatedDeclarations, verbatimModuleSyntax |
assembly loading, the module path of Java |
| 7 | At scale: project references, tsc -b, npm and pnpm workspaces, --generateTrace, the checker’s performance |
solutions, incremental builds, multi-module Maven builds |
| 8 | Decorators: the ECMAScript standard, metadata, and what changed from experimentalDecorators |
attributes, annotations |
| 9 | The compiler API and tooling: transforms, the language service, a typed typescript-eslint rule | Roslyn analyzers, annotation processors |
| 10 | The native compiler: TypeScript 7, what changed, compatibility, measurements | the move from the .NET Framework compilers to Roslyn |
| 11 | Type tests: expect-type, tsd, vitest --typecheck |
tests of a public API, analyzers’ tests |
| 12 | Library patterns: typed builders, fluent APIs, route inference, typed query builders | LINQ, Entity Framework, jOOQ |
| — | Journal |
Lessons 5 to 12 are planned and not written yet.
Prerequisites
Section titled “Prerequisites”- Node.js 24 and Git. On Windows, run the course script from Git Bash:
npm ci, thenbash check.shincode/typescript-advanced. - The .NET 10 SDK and a JDK 25, only for the comparisons;
check.shskips them whendotnetorjavais missing.
Related courses on this site
Section titled “Related courses on this site”- TypeScript for C#/Java developers: the language this course builds on.
- JavaScript for C#/Java developers: what runs once the types are erased.
- Advanced C#: the same kind of course for C#, on the same GA repository.
Resources
Section titled “Resources”- The TypeScript Handbook, in particular Type Manipulation, and the TSConfig reference.
- The TypeScript release notes: most features of this course arrived in a release between 4.1 and 5.4, and each lesson links the one that introduced it.
- microsoft/typescript-go, the compiler in Go, whose
internal/checker/checker.goholds the limits quoted in lesson 1, and microsoft/TypeScript, the compiler in TypeScript up to version 6. - Standard Schema, the interface shared by the validation libraries of lesson 4.
- ECMAScript® Language Specification, and Node.js 24 — Modules: TypeScript.