Learn Rust Before C. Your TypeScript Will Notice.
Abstract
Rust and TypeScript teach each other, and Rust is a better first deep dive into how computers work than C or C++. Partway through learning it, here is why.
From the Middle of the Climb
I am not a Rust expert. I am partway up the learning curve, which is the only honest place to write about a learning curve from.[1] Experts forget what was hard. I still remember.
Two claims. Rust and TypeScript make each other easier to learn. And if you want the deep dive into how computers really work, Rust is a better first stop than C or C++.
What Rust Did to My TypeScript
Rust has no null. A value that might be missing is an Option, and a thing that might fail returns a Result. The compiler makes you handle both cases before it lets you continue. You cannot forget.
Here is the whole idea in a few lines of Rust:
fn first_char(s: &str) -> Option<char> {
s.chars().next()
}
fn main() {
match first_char("rust") {
Some(c) => println!("starts with {c}"),
None => println!("empty string"), // forget this arm and it will not compile
}
}
And the same idea in TypeScript, as a union. With strict on, it holds you to the same discipline:
function firstChar(s: string): string | undefined {
return s[0];
}
const c = firstChar("rust");
if (c === undefined) {
console.log("empty string");
} else {
console.log(`starts with ${c}`);
}
Once that clicked, my TypeScript looked different. A type like string | undefined stopped being something the compiler nags about and became a design decision: this value can be absent, and everyone who touches it has to deal with that. Discriminated unions, the never trick for exhaustive switch statements, strict null checks: these are TypeScript’s version of the same idea. Rust is where the idea is law instead of a suggestion.
And Back the Other Way
If you already write TypeScript, you speak half of Rust’s dialect before you start. Types are the thing you design first. Generics do not scare you. Traits are, roughly, interfaces with stricter manners. Enums that carry data look a lot like discriminated unions with a better publicist.
TypeScript also gives you what Rust cannot: a feedback loop measured in seconds and an ecosystem for everything. Prototype the idea there, then learn what it costs in Rust.[2]
Ownership: The Thing JavaScript Never Asked
In JavaScript you create objects and the garbage collector quietly handles the rest. Nobody asks who owns what, or when it dies.
Rust asks constantly. Every value has one owner. When the owner goes away, the value goes away. You can lend it out, to many readers or to one writer, never both at once. At first this feels like arguing with a very strict librarian. Then it changes how you think: you start seeing where data lives, who is holding it, and how long it needs to exist. That is what C and C++ are supposed to teach you, and exactly what a garbage-collected language hides.
The smallest version of the argument looks like this:
fn main() {
let a = String::from("hi");
let b = a; // ownership moves to b
println!("{a}"); // error[E0382]: borrow of moved value: `a`
}
The Compiler as a Teacher
C teaches by punishment. You do something wrong with memory, the program compiles anyway, and the lesson arrives later as a crash, or worse, as a program that works until it doesn’t. Learning memory safety from a segfault is a bit like learning fire safety from the fire.
Rust moves the lesson earlier. The compiler refuses, points at the line, names the rule you broke, and often suggests the fix. Every error code has a longer explanation behind it, available with rustc --explain. The message is a short lesson delivered at the exact moment you need it.
Ask it about the error above:
rustc --explain E0382
Rust Instead of C and C++, for the Deep Dive
For many developers, the deep dive into how computers work was C or C++: pointers, stack and heap, what happens when you call a function. That rite of passage is worth keeping. I just think Rust is a better way to do it, and the objections to that are fair, so here is what I concede.
“The borrow checker hides the machine.” Partly. But it does not hide the stack, the heap, references or lifetimes. It makes them visible and named, where C leaves them implicit and lets you get them wrong in silence. And when you do need the raw machine, Rust has unsafe, which is an honest label on the dangerous part.
“The learning curve is brutal.” Yes. But the pain is front-loaded, and the compiler is on your side. C’s pain comes later and is sneakier: a bug can sit in your code for a year before it bites.
“C and C++ are where the legacy and the jobs are.” True, and I am not saying never learn them. A lot of the world runs on them. I am saying they do not have to be your first deep dive. Learn the concepts where the compiler explains them. Read C on the day you need to, when it will feel less like a cliff.
Conclusion
Rust and TypeScript are not rivals. One gives you a fast, forgiving place to build things; the other shows you what the fast place is doing for you. Learn Rust, and you will write TypeScript differently. Learn TypeScript first, and Rust looks less alien. And if the goal is to finally understand memory, start where the compiler explains the rules instead of where the crash does.
Reviewer 2 will point out that none of this is new. Reviewer 2 is correct, and has also not read it.