Capítulo 26 de 36

Chapter 26: Symbols

Core Idea

symbol is a JS primitive (since ES2015) for creating guaranteed-unique values, usable as object/class member keys — TypeScript adds the unique symbol subtype to let specific symbol declarations be tracked individually by identity in the type system.

Key Concepts

  • Creation and uniqueness: Symbol() / Symbol("description") produce a new primitive value every call — two symbols created with the same description string are still different values (Symbol("key") === Symbol("key") is false). Immutable, and usable as a computed property key (obj[sym] = "value") on plain objects or as a computed class member name.
  • unique symbol: a subtype of symbol reserved for symbols whose identity the type system should track individually rather than treating generically as "some symbol." Only producible from Symbol()/Symbol.for() calls or explicit annotations, and only allowed on const declarations or readonly static class properties. To reference one elsewhere, use typeof thatSymbol — each unique symbol type is tied to exactly one declaration, so no two distinct unique symbol types are ever assignable to or comparable with each other (comparing two independently-created symbols with === is flagged, since the comparison can statically never be true).
  • Well-known symbols: built-in symbols the language itself hooks into for internal behaviors — the mechanism behind several standard protocols:
SymbolHooked by
Symbol.iteratorfor..of — default iterator
Symbol.asyncIteratorfor await..of — default async iterator
Symbol.hasInstanceinstanceof — custom instance-check logic
Symbol.isConcatSpreadableArray.prototype.concat — whether to flatten into elements
Symbol.match / Symbol.replace / Symbol.search / Symbol.splitString.prototype.match/replace/search/split — custom regex-like matcher objects
Symbol.specieswhich constructor derived objects (e.g. from .map()/.filter()) get created with
Symbol.toPrimitivethe ToPrimitive coercion algorithm — custom primitive conversion
Symbol.toStringTagObject.prototype.toString — customizes the default "[object Tag]" string
Symbol.unscopablesexcludes named properties from legacy with statement bindings

Code Examples

class C {
  static readonly StaticSymbol: unique symbol = Symbol();
}
let ref: typeof C.StaticSymbol = C.StaticSymbol; // OK — same identity
  • What it demonstrates: declaring a unique symbol as a readonly static class member and referencing its exact identity elsewhere via typeof.

Key Takeaways

  1. Use plain symbol for "any symbol value"; reach for unique symbol (on a const or readonly static) only when the type system needs to distinguish one specific symbol's identity from every other symbol.
  2. Comparing two independently-created symbols for equality is always statically false — TypeScript will flag an obviously-impossible === between two distinct unique symbol-typed values.
  3. Symbol.iterator (this chapter) is the same protocol the Iterators and Generators chapter's Iterable<T> relies on — it's how for..of actually finds what to iterate.

Connects To

  • Iterators and Generators: Symbol.iterator is the foundation of the whole iterable/for..of protocol.
  • Object Types: computed property keys and index signatures, the mechanics symbols plug into as object/class members.