ProgrammingFrontend Developer

Explain how the typeof guard operator works in TypeScript, how and why it is used, and what its limitations are.

Pass interviews with Hintsage AI assistant

Answer.

Background

In JavaScript, the typeof operator is used to check the type of primitive values at runtime. TypeScript extends this mechanism and makes it part of the type narrowing system through type guards. TypeScript uses the result of the typeof operator to refine the type of a variable within a block of code, allowing for a more accurate description of function logic, especially when working with union types.

Problem

In regular JavaScript, after checking the type of a value using typeof, there is no type guarantee — the programmer must remember what happens at each section of the code. However, in TypeScript, the task is complicated by the presence of different types and union types, and without correct type narrowing, it is easy to make a mistake, such as calling a non-existent method. Additionally, the operator has specific limitations: it "sees" only basic primitive types, for example, it will return 'object' for arrays and objects.

Solution

TypeScript allows combining the typeof operator with custom type analysis to narrow the type of a variable within a block of code. This automatically increases safety — the compiler knows what type the code is working with and suggests possible properties and methods.

Code example:

function printId(id: number | string) { if (typeof id === 'string') { // In this branch id: string console.log(id.toUpperCase()); } else { // In this branch id: number console.log(id.toFixed(2)); } }

Key features:

  • Works only with primitives: 'string', 'number', 'boolean', 'symbol', 'undefined', 'object', 'function', 'bigint'.
  • Helps TypeScript narrow a union type down to a specific primitive within a block of code.
  • Does not distinguish between arrays and objects, always returns 'object' for them.

Trick Questions.

Can the typeof operator determine an array?

No, typeof will return the same value — 'object' — for both an array and an object. To distinguish arrays, it's better to use the Array.isArray() method.

Code example:

const arr = [1, 2, 3]; console.log(typeof arr); // 'object' console.log(Array.isArray(arr)); // true

Can typeof distinguish null and an object?

No, typeof null returns 'object', this is a historical feature of JavaScript.

Code example:

console.log(typeof null); // 'object'

Can typeof check a user-defined class?

No, for class instances typeof will also return 'object'. For this, the instanceof operator or custom type guard functions are used.

Code example:

class User {} const u = new User(); console.log(typeof u); // 'object' console.log(u instanceof User); // true

Type Errors and Anti-Patterns

  • Using typeof to check complex data structures (like arrays, null, objects).
  • Neglecting the use of instanceof and Array.isArray() operators for more precise type narrowing.
  • Type checking only at runtime, ignoring static checks.

Real-Life Example

Negative case

A programmer wrote a function where they wanted to check if the value was an array using typeof and based on the result call different methods.

Pros:

  • Code is simply written.
  • Doesn’t require additional functions.

Cons:

  • Function breaks when an array is passed: the array is treated as an object, causing runtime errors.

Positive case

Using Array.isArray and combining it with a type guard.

Pros:

  • Safe static typing.
  • No errors with types of objects versus arrays.

Cons:

  • Need to remember various type guard tools.