Special Types: any, unknown, union & literal
Sometimes a value can be more than one type — TypeScript has clever tools for exactly that.
What you will learn
- Avoid the trap of any and prefer unknown
- Allow a few types with a union
- Lock a value to exact options with literal types
any — the escape hatch (use sparingly)
The type any means "turn checking off for this value". It accepts anything — which sounds handy but throws away all the safety TypeScript gives you.
let data: any = 'hello';
data = 42; // allowed
data.toUpperCase(); // no error... but 42 has no toUpperCase!Note: Output:
(Compiles fine, but CRASHES at runtime: data.toUpperCase is not a function.)
With any, TypeScript stops protecting you. The bug sails through and explodes when the code runs.
Watch out: Treat any like a fire exit: only when you are truly stuck. Reaching for any everywhere turns TypeScript back into plain JavaScript.
unknown — the safe version of any
unknown also holds any value, but it forces you to check the type first before using it. It is the safe choice when you genuinely do not know the type yet.
let input: unknown = 'hello';
if (typeof input === 'string') {
console.log(input.toUpperCase()); // safe — we checked it is a string
}Note: Output:
HELLO
Because we tested typeof input === 'string' first, TypeScript now trusts that inside the if, input really is a string.
Union types — "this OR that"
A union uses a vertical bar | to say a value may be one of several types. Great for things like an id that could be a number or a string:
let id: number | string;
id = 101; // ok
id = 'A101'; // also ok
id = true; // error — boolean is not in the unionNote: Output:
Error: Type 'boolean' is not assignable to type 'string | number'.
number | string accepts only those two types. A boolean is not allowed.
Literal types — exact allowed values
You can go even narrower: a literal type limits a value to specific exact options, not just a broad type. Perfect for a status with only a few valid words:
let status: 'active' | 'paused' | 'closed';
status = 'active'; // ok
status = 'deleted'; // error — not one of the threeNote: Output: Error: Type '"deleted"' is not assignable to type '"active" | "paused" | "closed"'. Only the three listed words are allowed. Typos like 'actve' are caught at compile time.
Tip: Prefer unknown over any, and use literal unions for "a small fixed set of choices" — the editor will even autocomplete the valid options for you.
Q. Which type lets a value be a number OR a string, while still checking it?
✍️ Practice
- Declare
code: number | stringand assign a number, then a string. Try a boolean and read the error. - Make a
size: 'S' | 'M' | 'L'variable; assign 'M', then try 'XL'.
🏠 Homework
- Explain in two or three sentences why
unknownis safer thanany, with a tiny example.