Why does implicit Symbol to String conversion' lead to TypeError in JavaScript?

Is the latter just calling .toString() on a new Symbol and append (+) it to empty string?

No actually, Symbols cannot be implicitly cast to strings, or numbers, although interestingly enough you can implicitly cast them to a boolean.

MDN actually has a section on some of these pitfalls:

Symbol type conversions

Some things to note when working with type conversion of symbols.

  • When trying to convert a symbol to a number, a TypeError will be thrown (e.g. +sym or sym | 0).
  • When using loose equality, Object(sym) == sym returns true.
  • Symbol("foo") + "bar" throws a TypeError (can't convert symbol to string). This prevents you from silently creating a new string property name from a symbol, for example.
  • The "safer" String(sym) conversion works like a call to Symbol.prototype.toString() with symbols, but note that new String(sym) will throw.

This behavior is documented in the spec under the abstract ToString operation:

Argument Type: Symbol

Result: Throw a TypeError exception.

And similarly for abstract ToNumber operation:

Argument Type: Symbol

Result: Throw a TypeError exception.

To cast a Symbol to a string without a TypeError, you must use either the toString method, or String().


From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toString.

The Symbol object overrides the toString method of the Object object; it does not inherit Object.prototype.toString(). For Symbol objects, the toString method returns a string representation of the object.