Skip to content

Rust You Won't Find in TypeScript

TypeScript is an excellent language. But it runs on a garbage-collected JavaScript runtime. That runtime makes many hard decisions invisible: when is memory freed? Who owns a value? Can two threads read the same object at the same time?

Rust makes all of these decisions explicit — at compile time, with zero runtime cost. That means Rust has a set of concepts with no equivalent in TypeScript at all. This module covers them.

In TypeScript (and JavaScript), you never think about memory:

TypeScript
// TypeScript — memory is invisible
const greeting = "hello"; // allocated on the heap, somewhere
const copy = greeting; // both point to the same string object
// When does "hello" get freed? The GC decides. You never know.
// There is no ownership. There are no rules. Just references.
function process(s: string) {
console.log(s);
}
process(greeting);
console.log(greeting); // still valid — GC keeps it alive
Rust
fn main() {
// Rust — ownership is explicit
let s = String::from("hello"); // s owns the string data
let t = s; // ownership MOVES to t; s is gone
// println!("{}", s); // compile error: s was moved
println!("{}", t); // only t is valid
// borrowing — temporary access without moving
let greeting = String::from("world");
let len = calc_len(&greeting); // lend greeting; we keep ownership
println!("{} has {} chars", greeting, len);
// Copy type — i32 is cheap to copy, so it copies automatically
let x: i32 = 42;
let y = x; // x is NOT moved — it is copied
println!("x={} y={}", x, y); // both valid
}
fn calc_len(s: &String) -> usize {
s.len()
}
fn main() {
// move semantics
let s = String::from("hello");
let t = s; // s is moved into t
println!("{}", t); // only t is valid
// borrowing
let greeting = String::from("world");
let len = calc_len(&greeting);
println!("{} has {} chars", greeting, len);
// Copy type
let x: i32 = 42;
let y = x; // i32 is Copy — both x and y are valid
println!("x={} y={}", x, y);
}
fn calc_len(s: &String) -> usize {
s.len()
}
Which of the following is handled by the Rust compiler — not a runtime?
What happens to `s` after `let t = s;` when `s` is a `String`?
Why does TypeScript never need ownership rules?