Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The typeof operator in TypeScript is a compile-time type query operator that extracts the inferred or explicitly declared type of an existing runtime value (such as a variable, object property, function, or class) and projects it into the type space. It allows developers to capture the structural shape or signature of existing bindings without duplicating declarations.

Type Space vs. Value Space

TypeScript distinguishes between the value space (runtime JavaScript) and the type space (compile-time TypeScript). The behavior of typeof depends entirely on the context in which it is invoked:
  • Value Context (JavaScript): Evaluates at runtime and returns a string indicating the operand’s runtime data type, which includes both primitives (e.g., "string", "number") and non-primitives (e.g., "object", "function"). In TypeScript, these runtime checks function as Type Guards. The compiler utilizes control flow analysis to narrow the type of a variable within a conditional block based on this runtime evaluation.
  • Type Context (TypeScript): Evaluates at compile-time and returns the exact TypeScript type signature of the identifier.
const user = { name: "Alice", age: 30 };

// Value context: JS typeof returns a string indicating the runtime data type. 
// TS uses this as a Type Guard for control flow analysis.
function process(val: string | typeof user) {
  if (typeof val === "string") {
    val.toUpperCase(); // TS narrows 'val' to string
  }
}

// Type context: TS typeof returns the type { name: string; age: number; }
type UserType = typeof user; 

Syntax and Operands

In a type context, the TypeScript typeof operator accepts identifiers, property access chains, and inline module imports. It cannot evaluate arbitrary expressions, mathematical operations, or function invocations. Valid Operands:
const config = { endpoint: "/api", retries: 3 };

// Identifier
type ConfigType = typeof config; 

// Property access chain
type EndpointType = typeof config.endpoint; // Type is 'string'

// Import type: Extracts the type of a module without a runtime import
type FsModule = typeof import("fs");
Invalid Operands:
function calculate() { return 42; }

// Error: Cannot use typeof on a function call expression
type Result = typeof calculate(); 

// Error: Cannot use typeof on an arithmetic expression
type MathResult = typeof (10 + 20); 

Behavior with Classes

In TypeScript, class declarations create both a type (representing the instance) and a value (the constructor function). Using a class identifier directly as a type refers to the instance type. To extract the constructor type—which includes the constructor signature and any static members—typeof must be applied to the class identifier.
class Database {
  static connectionLimit = 10;
  connect() {}
}

// Refers to the instance type: { connect: () => void }
let dbInstance: Database;

// Refers to the constructor type: new () => Database, plus static members
type DatabaseConstructor = typeof Database;

// Accessing static members on the constructor type
type LimitType = DatabaseConstructor["connectionLimit"]; // Type is 'number'

Behavior with Functions

When applied to a function identifier, typeof extracts the complete function signature, including parameter types and the return type. It does not execute the function.
function format(input: string, toUpper: boolean): string {
  return toUpper ? input.toUpperCase() : input;
}

// Type is: (input: string, toUpper: boolean) => string
type FormatFunction = typeof format;
To extract only the return type of a function, typeof must be composed with the ReturnType utility type:
// Type is: string
type FormatReturn = ReturnType<typeof format>;

Interaction with Literal Widening

By default, TypeScript widens the types of mutable variables. typeof captures this widened type. If the target value is declared with a const assertion (as const), typeof captures the exact, narrowed literal type, including readonly modifiers.
const mutableColors = ["red", "blue"];
// Type is: string[]
type MutableType = typeof mutableColors;

const immutableColors = ["red", "blue"] as const;
// Type is: readonly ["red", "blue"]
type ImmutableType = typeof immutableColors;
Master TypeScript with Deep Grasping Methodology!Learn More