Skip to main content

Extreme Explorations of TypeScript's Type System

· 20 min read

TypeScript's type system is Turing Complete: meaning it has conditional branching (conditional types) and works with an arbitrary huge amount of memory. As a result, you can use the type system as its own programming language complete with variables, functions, and recursion. Developers have pushed the bounds of type operations possible in the type system to write some pretty incredible things!

This blog post is a starting list of nifty things TypeScript developers have pushed the type system to be able to do. They range from binary arithmetic and rudimentary virtual machines to maze solvers and full programming languages.

✋ This Is Not Normal

Most applications try to get away with as few extreme type operations as possible. Complex logic in the type system gets unreadable and hard to debug pretty quickly. The Learning TypeScript book advises:

If you do find a need to use type operations, please—for the sake of any developer who has to read your code, including a future you—try to keep them to a minimum if possible. Use readable names that help readers understand the code as they read it. Leave descriptive comments for anything you think future readers might struggle with.

Please don't look at the following projects list and think you need to understand them to use TypeScript. These projects are ridiculous. They're the equivalent of code golf: a fun activity for a select few, but not useful for most day-to-day work.

Projects List

Sorted oldest first. All projects listed come with explanations explaining how they work.

4-Bit Virtual Machine

Ashley Claymore, September 2019

So...a joke with a colleague at work got a little bit out of hand. I wrote a 4-Bit Virtual Machine in @typescript, using just Types, no JavaScript.

This well-documented set of types sets up a "virtual machine" that allows for manipulating a 4-bit stack. Its exported VM type takes in an array of program instructions such as "push" and "peek", and simulates manipulating the stack for each instruction. It even comes with a fizz buzz implementation in 20 commands. Very impressive.

Binary Arithmetic

Josh Goldberg, October 2019

type Bit = 0 | 1;

This project also implements low-level bit manipulation logic in the type system. It's less extensive than the 4-bit VM, and "just" includes 8-bit integer manipulation instead.

Maze Solver and More

Ronen Amiel, February 2020

This project attempts to push TypeScript's type system to its limits by actually implementing various functions and algorithms, purely on top of the type system.

Ronen made available not just a shortest-path maze solver in the type system, but also a whole suite of functions including number arithmetic, list operations, array sorting algorithms, and puzzle solving. Its puzzle solutions in particular stand out as great, well-commented uses of many type system features.

Fizz Buzz

Gal Schlezinger, February 2020

This blogpost shows how to implement FizzBuzz in TypeScript using types only — with no runtime code whatsoever.

This crafty approach walks through how to set up recursive logic and number arithmetic purely in the type system. It ends with a full FizzBuzz implementation that works on numbers.

TXState

Devansh Jethmalani, August 2020

An effort to statically type xstate.

XState is a popular library for state machines and state charts in JavaScript and TypeScript. TXState manages to take those features and run them entirely in the type system. The full Twitter thread shows Devansh's journey writing it over several months and links to some insightful discussions on various threads.

Devansh also has a fascinating type predicate eDSL project that makes heavy use of parsing in the type system: @sthir/predicate.

SQL Database Engine

Charles Pick, September 2020

A SQL database implemented purely in TypeScript type annotations.

The first entry in this list that extensively makes use of string parsing in the type system. Queries are run by parsing raw SQL strings into statements that are then evaluated against the current state of the database. It supports SELECT statements that return type system array of objects, as well as INSERT, UPDATE, and DELETE statements that return new database contents as a type.

Language Interpreter

Ronen Amiel, October 2020

A tiny language interpreter implemented purely in TypeScript's type-system.

Another fun project from Ronen: this time, an entire language! It supports a Lisp-like syntax with commands such as add, join, and or, as well as functions and variables. You have to wonder whether you could implement TypeScript itself in that language...

Tic Tac Toe

Josh Goldberg, October 2020

[We'll figure] how to take a template string literal, simulate a Tic Tac Toe game on it, and determine out who the winner of that game is.

This fun conference talk addition uses template literal string parsing to convert a description of game steps into a game board with pieces placed on it. Checking for a game victory is done with a set of assignability checks on the board's tuples.

Tokenizer + Parser + Interpreter

Anurag Hazra, April 2022

An experimental tokenizer/parser/interpreter written entirely on type-level to push the limits of TypeScript's type system.

Each part of tokenization, parsing, and interpreting is impressive. This project takes them all to the next level by implementing a fully working language in the type system. Absolutely ridiculous.

Anurag has a collection of other great type system explorations on GitHub too: github.com/anuraghazra/type-trident.

HypeScript

Ronen Amiel, July 2022

Turns out it's possible to implement TypeScript's type system in TypeScript's type system 😳.

Another creation by Ronen, this is a simplified implementation of TypeScript's type system that's written in TypeScript's type annotations. It implements a surprisingly large subset of the type system: variables, functions, arrays, objects, and more!

N-Queens

Richard Towers, March 2023

“Okay, that looks like a correct solution, but the code is quite hard to follow, and it’s not very concise.” he asserts, wrongly.

“Oh it’s mostly just TypeScript boilerplate. I think you’ll find once it’s compiled down to JavaScript it’s perfectly concise.” you reassure him.

In the form of a technical interview, Richard shows us how TypeScript's type system solves a puzzle, "N-Queens". Given an NxN chessboard, you need to find a way to place N queens on that board safely. A queen threatens another if she is in the same row, column, or diagonal.

Type System Chess

Daniel James, July 2023

This repo contains chess implemented entirely in the (stable) Rust and Typescript type systems. Both languages feature turing complete type systems making this possible.

Near-complete chess implementations in two type systems, including castling, promotion, and en passant. TypeScript's version also includes string parsing for a Forsyth–Edwards Notation (FEN) parser.

Binary Arithmetic and Sorting

Denis Lukichev, August 2023

The primary objectives are to add numbers and sort an array of numbers, all at the type level, without any runtime execution. ... This might just make TypeScript the fastest language in the universe, with a runtime of precisely zero. 😉️ Just a bit of fun, but it's fascinating what's possible, isn't it?

This fun project expands on the idea of representing numbers as tuples by adding both binary arithmetic and merge sorting.

More Resources

If the explanations in projects aren't working out for you, I have two resources I'd recommend:

Additionally, the type-challenges repository on GitHub contains a wonderful suite of type challenges starting with foundations and working up to gloriously complex metaprogramming. I'd highly recommend using them to work your way up to being able to make projects like the ones in this article.

info

Got a project you think should be listed? Send it to @LearningTSBook on Twitter!