TypeScript Types: Your Toolbox of Labels! 🏷️
Imagine you have a magical toy box. But this isn’t just any toy box—it has special compartments, and each compartment only accepts certain toys. Put a car in the “cars only” slot? Perfect! Try to squeeze a teddy bear in there? Nope, won’t fit!
TypeScript types work exactly like that. They’re labels that tell your code: “Hey, only THIS kind of thing goes here!”
The Story: Meet the Type Family
Think of types as a big family living in TypeScript Town. Each family member has a special job, and together they keep your code safe and organized.
🧱 Primitive Types: The Foundation Family
These are the basic building blocks—the simplest, most common types you’ll use every day.
string - The Storyteller
Holds text—words, sentences, names.
let greeting: string = "Hello!";
let name: string = 'Alice';
number - The Counter
Holds any number—whole, decimal, negative, positive.
let age: number = 25;
let price: number = 19.99;
let temperature: number = -5;
boolean - The Yes/No Decider
Only two answers: true or false. Like a light switch!
let isHappy: boolean = true;
let isRaining: boolean = false;
graph TD A["Primitive Types"] --> B["string"] A --> C["number"] A --> D["boolean"] B --> E["'Hello'"] C --> F["42, 3.14"] D --> G["true / false"]
🔢 bigint - The Giant Number Handler
Regular numbers have limits. But what if you need to count all the stars in the universe? Enter bigint!
let reallyBigNumber: bigint = 9007199254740991n;
let anotherHuge: bigint = BigInt(12345678901234567890);
Notice the n at the end? That’s how JavaScript knows: “This is a bigint, not a regular number!”
💡 Real-Life Example: Banks use bigint to track very large transactions accurately.
🎯 symbol - The Unique ID Maker
Every symbol is 100% unique—like a fingerprint. Even if two symbols have the same description, they’re different!
let id1: symbol = Symbol("id");
let id2: symbol = Symbol("id");
console.log(id1 === id2); // false! They look same but aren't
💡 Why use it? When you need keys that will NEVER accidentally clash with other keys.
🕳️ null and undefined - The Empty Twins
These two represent “nothing,” but in slightly different ways.
undefined - “I haven’t been given a value yet”
let notYetAssigned: undefined = undefined;
let someVar: string | undefined;
console.log(someVar); // undefined (no value set)
null - “I intentionally have no value”
let emptyOnPurpose: null = null;
let user: string | null = null; // No user logged in
graph TD A["Empty Values"] --> B["undefined"] A --> C["null"] B --> D["Not assigned yet"] C --> E["Deliberately empty"]
🎯 Simple Rule:
undefined= forgot to fill innull= purposely left blank
🚫 void - The “I Return Nothing” Type
Functions sometimes do their job but don’t give anything back. That’s void!
function sayHello(): void {
console.log("Hello!");
// No return statement needed
}
function logMessage(msg: string): void {
console.log(msg);
}
💡 Think of it like: Clapping your hands. You do something, but you don’t get anything back in your hands.
☠️ never - The “This Will Never Happen” Type
This is the rarest type. It means: “This code will NEVER successfully finish.”
When does never appear?
1. Functions that always throw errors:
function crash(): never {
throw new Error("Boom!");
}
2. Infinite loops:
function forever(): never {
while (true) {
// Runs forever, never returns
}
}
🎯 Key insight: If a function returns
never, the code after it will NEVER run.
🌀 any - The “Anything Goes” Wildcard
any is like removing all the labels from your toy box. Anything can go anywhere!
let mystery: any = 5;
mystery = "now I'm text";
mystery = true;
mystery = { name: "Bob" };
// All of this works!
⚠️ Warning: Use Sparingly!
let data: any = "hello";
console.log(data.toFixed(2)); // No error... but CRASHES at runtime!
TypeScript won’t protect you when you use any. It’s like driving without a seatbelt.
💡 When to use: Only when migrating old JavaScript code or dealing with truly dynamic data you can’t predict.
🔒 unknown - The Safe Mystery Box
Like any, but with a safety lock! You must CHECK what’s inside before using it.
let userInput: unknown = "Hello";
// This WON'T work:
// console.log(userInput.length); // Error!
// This WILL work:
if (typeof userInput === "string") {
console.log(userInput.length); // Safe!
}
graph TD A["Mystery Value"] --> B{Check Type First} B -->|string| C["Use string methods"] B -->|number| D["Use number methods"] B -->|other| E["Handle appropriately"]
🎯 Rule:
unknownforces you to verify before you trust. It’sanywith training wheels!
📦 object - The “Not Primitive” Container
object means: “This is something complex, not a simple primitive.”
let person: object = { name: "Alice", age: 25 };
let numbers: object = [1, 2, 3];
let today: object = new Date();
What’s NOT an object?
let text: object = "hello"; // ERROR! string is primitive
let num: object = 42; // ERROR! number is primitive
let flag: object = true; // ERROR! boolean is primitive
💡 Better Practice: Instead of generic
object, define the exact shape:
let user: { name: string; age: number } = {
name: "Bob",
age: 30
};
🎯 Quick Comparison Chart
| Type | What it holds | Example |
|---|---|---|
string |
Text | "Hello" |
number |
Numbers | 42, 3.14 |
boolean |
True/False | true |
bigint |
Huge integers | 9999999999999n |
symbol |
Unique identifiers | Symbol("id") |
null |
Intentional nothing | null |
undefined |
Not yet assigned | undefined |
void |
Function returns nothing | function log(): void |
never |
Never completes | throw new Error() |
any |
Anything (unsafe) | Avoid if possible |
unknown |
Anything (safe) | Check before use |
object |
Complex structures | { }, [ ] |
🏆 You Made It!
Now you know the entire TypeScript type family! Remember:
- Primitives (
string,number,boolean) are your everyday heroes - bigint and symbol handle special cases
- null and undefined represent “empty”
- void means “no return value”
- never means “this never finishes”
- any is dangerous freedom
- unknown is safe mystery
- object holds complex stuff
Welcome to type-safe coding! 🚀
