TypeScript Special Types

TypeScript's special types - any, unknown, never, and void - handle the edges of the type system where values are absent, unpredictable, or intentionally unchecked.

The any type

The any type tells the compiler to skip type checking entirely for a value. It is the closest thing to plain JavaScript behavior available in TypeScript, and it should be used sparingly - typically only when migrating old JavaScript code or interfacing with a library that has no type information.

Example

let data: any = 4;
data = "now a string"; // allowed
data = { nested: true }; // also allowed
data.toUpperCase(); // no compile error, even though this could crash at runtime

The unknown type

unknown is a safer alternative to any. Like any, it can hold a value of any type, but TypeScript will not let you use that value until you have narrowed it down with a type check - for example using typeof. This forces you to prove what the value actually is before operating on it.

Example

let input: unknown = "42";

// input.toUpperCase(); // Error: Object is of type 'unknown'.

if (typeof input === "string") {
  console.log(input.toUpperCase()); // OK - narrowed to string
}

The void type

void describes the return type of a function that does not return a meaningful value - most commonly, functions used only for their side effects, like logging.

Example

function logMessage(message: string): void {
  console.log(message);
  // no return statement, or a bare 'return;' is fine
}

logMessage("Application started");

The never type

never represents a value that can never occur - typically the return type of a function that always throws an exception or never finishes (like an infinite loop). It is also used by the compiler to verify exhaustive checks across union types.

  • any - opts a value out of type checking entirely; use only as a last resort.
  • unknown - safe container for values of unknown type; must be narrowed before use.
  • void - the absence of a meaningful return value from a function.
  • never - a value or code path that is impossible to reach.

Example

function throwError(message: string): never {
  throw new Error(message);
}

function assertIsString(value: unknown): asserts value is string {
  if (typeof value !== "string") {
    throwError("Value is not a string");
  }
}
Note: Overusing any quietly disables the safety TypeScript is meant to provide. Prefer unknown whenever you truly do not know a value's type in advance.
Note: void and never look similar but differ in meaning: void means 'returns nothing useful', while never means 'never returns at all'.
TypeCan hold any value?Safe to use without narrowing?Typical use case
anyYesYes (unsafe)Migrating untyped JS, quick prototypes
unknownYesNo - must narrow firstValues from JSON.parse, external APIs
voidNo - represents no return valueN/AFunctions run only for side effects
neverNo - represents unreachable codeN/AFunctions that always throw; exhaustive checks

Exercise: TypeScript Special Types

What does assigning the `any` type to a variable do?