any, unknown, never & void
Understand TypeScript’s special-purpose types: the type-checking escape hatch any, the safer unknown, the unreachable never, and void.
Reading Time
14 min
Lesson
Lesson 6 of 30
The any Type
any disables type checking entirely for that value — you can assign anything to it and call anything on it with no compiler errors. It’s effectively an escape hatch back to plain JavaScript.
any Disables Type Safety
let data: any = "hello";
data = 42;
data.toUpperCase(); // No error at compile time, but crashes at runtimeThe unknown Type
unknown is the type-safe counterpart to any. It accepts any value too, but you can’t use it for anything until you first narrow it to a more specific type — forcing you to check before you use it.
unknown Requires Narrowing First
let data: unknown = "hello";
data.toUpperCase(); // Error: 'data' is of type 'unknown'
if (typeof data === "string") {
data.toUpperCase(); // OK — narrowed to string inside this block
}any vs unknown
| any | unknown | |
|---|---|---|
| Accepts any value | Yes | Yes |
| Usable without narrowing | Yes (unsafe) | No — must narrow first |
| Recommended for | Rarely — last resort | External/untrusted data, like API responses |
The never Type
never represents a value that can never occur — used for functions that always throw or never return, and for exhaustiveness checks in switch statements over a union type.
never in a Function That Always Throws
function throwError(message: string): never {
throw new Error(message);
}never for Exhaustiveness Checking
type Shape = "circle" | "square";
function area(shape: Shape) {
switch (shape) {
case "circle":
return "π × r²";
case "square":
return "side × side";
default:
const exhaustiveCheck: never = shape; // errors if a case is missing
return exhaustiveCheck;
}
}The void Type
void describes the return type of a function that doesn’t return a meaningful value — most commonly a function that only performs side effects, like logging.
void Return Type
function logMessage(message: string): void {
console.log(message);
}Avoid any Where Possible
Every any in a codebase is a place TypeScript can no longer catch bugs for you. Prefer unknown for genuinely unknown data, and only reach for any as a deliberate, temporary escape hatch.
Best Practice
Type external data (API responses, JSON.parse() results) as unknown, then validate and narrow it before use — this keeps the type system honest about what you’ve actually verified.