1. Basics
| Concept | TypeScript | Rust | Note |
|---|---|---|---|
console.log("hi") | println!("hi"); | Rust macro uses ! | |
| Variable | let x = 5; | let x = 5; | Looks same, but Rust is immutable by default |
| Mutable | let x = 5; x = 6; | let mut x = 5; x = 6; | Must use mut |
| Constant | const PI = 3.14; | const PI: f64 = 3.14; | Rust const needs type |
| Comments | // single, /* multi */ | // single, /* multi */ | Same |
2. Types
| TS | Rust | Example |
|---|---|---|
number | i32, i64, u32, f64 | let x: i32 = 5; |
string | String (heap), &str (borrowed) | let s: &str = "hi"; let s2: String = String::from("hi"); |
boolean | bool | let b: bool = true; |
any | β none | Must use enums or Box<dyn Any> |
null / undefined | Option<T> | let x: Option<i32> = None; |
array | Vec<T> | let arr: Vec<i32> = vec![1,2,3]; |
tuple | (T1, T2) | let tup: (i32, f64) = (5, 3.2); |
object | struct | struct User { name: String, age: i32 } |
union | enum | enum Shape { Circle(f64), Rect(i32,i32) } |
void | () | Function no return |
never | ! | Function never returns |
3. Functions
| TS | Rust | Example | |||||
|---|---|---|---|---|---|---|---|
function add(a:number,b:number):number { return a+b; } | fn add(a: i32, b: i32) -> i32 { a+b } | return type after -> | |||||
| Arrow function | (a,b)=>a+b | `let add = | a: i32,b: i32 | a+b;` | closures use ` | ` | |
| Default param | f(x=5) | No direct, use Option or overload | |||||
| Overload | function f(x:string):string; function f(x:number):number; | Use enum or traits | Rust doesnβt support direct overload |
4. Control Flow
| Concept | TypeScript | Rust |
|---|---|---|
| If | if (x>0) {} | if x > 0 {} |
| Else if | else if | else if |
| Switch | switch(x){case 1:...} | match x {1=>...,2=>..., _=>...} |
| Loop | for(let i=0;i<5;i++) | for i in 0..5 {} |
| While | while(x>0){} | while x>0 {} |
| Do-while | do {} while(x) | loop { if !cond { break; } } |
| Break | break; | break; |
| Continue | continue; | continue; |
5. Data Structures
Array
ts
let arr:number[] = [1,2,3];
arr.push(4);
console.log(arr[0]);rust
let mut arr: Vec<i32> = vec![1,2,3];
arr.push(4);
println!("{}", arr[0]);Tuple
ts
let tup:[string, number] = ["age", 20];rust
let tup: (&str, i32) = ("age", 20);Object β Struct
ts
type User = { name: string, age: number }
let u:User = { name:"boss", age:22 };rust
struct User { name: String, age: i32 }
let u = User { name: "boss".to_string(), age: 22 };Enum
ts
enum Shape { Circle, Square }
let s:Shape = Shape.Circle;rust
enum Shape { Circle, Square }
let s: Shape = Shape::Circle;With data:
ts
enum Shape { Circle(r:number), Rect(w:number,h:number) }rust
enum Shape { Circle(f64), Rect(i32,i32) }6. Option, Result (null/undefined replacement)
ts
function find(x?:number):number|null {
return x ?? null;
}rust
fn find(x: Option<i32>) -> Option<i32> {
x
}Error handling:
ts
function div(a:number,b:number):number {
if(b==0) throw new Error("zero");
return a/b;
}rust
fn div(a:i32,b:i32) -> Result<i32,String> {
if b==0 { return Err("zero".to_string()); }
Ok(a/b)
}7. Strings
ts
let s = "hi";
let s2 = s + " boss";rust
let s = "hi".to_string();
let s2 = s + " boss"; // needs StringInterpolation:
ts
let name="boss";
console.log(`Hi ${name}`);rust
let name="boss";
println!("Hi {}", name);8. Ownership & Borrowing (new concept)
-
TS has GC β Rust has ownership
-
Rules:
- One variable owns memory
- Move happens on assignment
- Borrow with
& - Mut borrow with
&mut
Example:
rust
let s = String::from("hi");
let t = s; // move, s not usable
let u = &t; // borrow, ok9. OOP Style
Class
ts
class User {
constructor(public name:string) {}
hello(){ console.log("hi " + this.name); }
}rust
struct User { name: String }
impl User {
fn new(name:String) -> Self { Self { name } }
fn hello(&self) { println!("hi {}", self.name); }
}10. Generics
ts
function id<T>(x:T):T { return x; }rust
fn id<T>(x:T) -> T { x }11. Traits vs Interfaces
ts
interface Printable { print():void }
class A implements Printable { print(){console.log("A")} }rust
trait Printable { fn print(&self); }
struct A;
impl Printable for A { fn print(&self){ println!("A"); } }12. Async / Await
ts
async function f(){ return 5; }
await f();rust
async fn f() -> i32 { 5 }
f().await;(Need runtime like tokio)
13. Modules
ts
// user.ts
export function hi(){console.log("hi");}
// main.ts
import {hi} from "./user";rust
// user.rs
pub fn hi(){ println!("hi"); }
// main.rs
mod user;
use user::hi;14. Pattern Matching (Rust power)
ts
let shape:Shape = Shape.Circle;
switch(shape){ case Shape.Circle: ... }rust
match shape {
Shape::Circle => println!("circle"),
Shape::Square => println!("square"),
}15. Error Handling Summary
- TS:
try { } catch(e) { } - Rust:
Result<T,E>+match+?
rust
fn main() -> Result<(), String> {
let x = div(10,2)?;
println!("{}", x);
Ok(())
}16. Tooling
| TS | Rust |
|---|---|
| npm/yarn/pnpm | cargo |
| tsconfig.json | Cargo.toml |
| tsc | rustc |
| node index.js | cargo run |
| jest | cargo test |
| eslint | clippy (cargo clippy) |
| prettier | rustfmt (cargo fmt) |
17. Tiny Full Example
TypeScript
ts
type Shape = { kind:"circle", r:number } | { kind:"rect", w:number,h:number }
function area(s:Shape):number {
switch(s.kind){
case "circle": return Math.PI*s.r*s.r;
case "rect": return s.w*s.h;
}
}
console.log(area({kind:"circle", r:2}));Rust
rust
enum Shape { Circle(f64), Rect(i32,i32) }
fn area(s:Shape) -> f64 {
match s {
Shape::Circle(r) => std::f64::consts::PI * r * r,
Shape::Rect(w,h) => (w*h) as f64,
}
}
fn main(){
println!("{}", area(Shape::Circle(2.0)));
}