← Back to TypeScript Course | Chapter 21: Symbols and Iterators | Lesson 1 of 6

Symbol Type

The symbol primitive represents unique identifiers that can be used as object property keys. Symbols are useful when you need properties that should not collide with ordinary string keys.
Syntax
typescript
const sym: symbol = Symbol("description");

Creating Symbols

Calling Symbol() creates a unique symbol value — every single call produces a genuinely distinct symbol, even if you pass the exact same description string to two different calls.

Example: Creating Symbols

typescript
const a = Symbol("id");
const b = Symbol("id");
console.log(a === b);

Symbols as Object Keys

A symbol can be used as a computed property key on an object, and that property can only be accessed again using the exact same symbol reference — no other symbol or string will reach it.

Example: Symbols as Object Keys

typescript
const idKey = Symbol("id");
const user = { name: "Ravi", [idKey]: 42 };
console.log(user[idKey]);

Symbol Properties and Enumeration

Symbol-keyed properties are deliberately invisible to Object.keys and normal for...in enumeration, though Object.getOwnPropertySymbols can retrieve an object's symbol keys if you specifically go looking for them.

Example: Symbol Properties and Enumeration

typescript
const idKey = Symbol("id");
const user = { name: "Ravi", [idKey]: 42 };
console.log(Object.keys(user));
console.log(Object.getOwnPropertySymbols(user));

Symbol Registry

Symbol.for creates or retrieves a symbol from a global, shared registry keyed by string — unlike Symbol(), two calls to Symbol.for with the same key return the exact same symbol.

Example: Symbol Registry

typescript
const a = Symbol.for("shared");
const b = Symbol.for("shared");
console.log(a === b);

Symbols in APIs

Symbols are how JavaScript defines special object protocols internally (like Symbol.iterator) and let independent pieces of code add properties to shared objects without any risk of colliding property names.

Example: Symbols in APIs

typescript
class Range {
  constructor(private start: number, private end: number) {}
  [Symbol.iterator]() {
    let current = this.start;
    const end = this.end;
    return {
      next: () => current < end
        ? { value: current++, done: false }
        : { value: undefined, done: true },
    };
  }
}
console.log([...new Range(1, 4)]);
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Comparing two symbols created with the same description and expecting true, when Symbol("id") === Symbol("id") is false.
  2. Using new Symbol(), which throws a TypeError since Symbol is not a constructor.
  3. Expecting Object.keys or JSON.stringify to show symbol-keyed properties, which they skip.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.