I like programming languages where variables are immutable by default. For example, in Rust, let declares an immutable variable and let mut declares a mutable one. I’ve long wanted this in other languages, like TypeScript, which is mutable by default—the opposite of what I want!
I wondered: is it possible to make TypeScript values immutable by default?
My goal was to do this purely with TypeScript, without changing TypeScript itself. That meant no lint rules or other tools. I chose this because I wanted this solution to be as “pure” as possible…and it also sounded more fun.
I spent an evening trying to do this. I failed but made progress! I made arrays and Record s immutable by default, but I couldn’t get it working for regular objects. If you figure out how to do this completely, please contact me—I must know!
Step 1: obliterate the built-in libraries
TypeScript has built-in type definitions for JavaScript APIs like Array and Date and String . If you’ve ever changed the target or lib options in your TSConfig, you’ve tweaked which of these definitions are included. For example, you might add the “ES2024” library if you’re targeting a newer runtime.
My goal was to swap the built-in libraries with an immutable-by-default replacement.
The first step was to stop using any of the built-in libraries. I set the noLib flag in my TSConfig, like this:
{ "compilerOptions": { "noLib": true } }
Then I wrote a very simple script and put it in test.ts :
... continue reading