Using JavaScript Symbol.toStringTag for objects types description
Tags: javascript, code, tutorial, example
Published: 2021-05-04 13:42:10

A day ago I asked my developers friends:

>How to know a JavaScript [object literal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer) type?

Most of the answers of the answers suggested to use [instanceof](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof), while this answer works for objects created by using a [constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/constructor), it can not work with objects literals or maybe for some reasons developers don't export the object constructor from the module but they provide a factory with object initializer instead.

## The use case:
The question was about the following use case:

```js
const user = {
   username: 'johndoe',
   firstname: 'John',
   lastname: 'Doe'
};
```

**It is hard to determine if the object above is in certain type without checking the presence of all the properties, imagine if we have a more than 10 properties or more, it would be exhausting, right?
It is obvious it would be good if we can know that the object is indeed in `User` type just by a single call.**

Using [`Object.prototype.toString()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString) gives the object type inside square brackets for the built-in types/objects:

```js
console.log(Object.prototype.toString.call(1)); // -> '[object Number]'
console.log(Object.prototype.toString.call('Cherif')); // -> '[object String]'
```
Or:

```js
const one = 1;
const name = 'Cherif';

console.log(one.toString()); // -> '[object Number]'
console.log(name.toString()); // -> '[object String]'
```

But for a developer defined objects it gives a `[object Object]` result, a generic object:

```js
const user = {
   username: 'johndoe',
   firstname: 'John',
   lastname: 'Doe'
};

console.log(user.toString()); // -> '[object Object]'
console.log(Object.prototype.toString.call(user)); // -> '[object Object]'
```

## Symbol.toStringTag to the rescue

Fortunately with the introduction of ES6 [`Symbol`s](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) a number of built-in symbols had seen the day make it possible to describe custom objects type by overriding `Object.prototype.toString()` using [`Symbol.toStringTag`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag), so to describe a type for our `user` object we can do the following:

```js
const user = {
   username: 'johndoe',
   firstname: 'John',
   lastname: 'Doe',
   get [Symbol.toStringTag]() {
       return 'User'; // The string tag description
   }
};

console.log(user.toString(user)); // -> '[object User]'
console.log(Object.prototype.toString.call(user)); // -> '[object User]'
```

## Read the string using Symbol.toStringTag:

I would advice to make the check using the `Symbol` property by using `user[Symbol.toStringTag]`, like this we have the possibility to override `toString` function for other purposes, and we can just have `User` string from the string tag instead of `[object User]` example:

```js
const user = {
   username: 'johndoe',
   firstname: 'John',
   lastname: 'Doe',
   get [Symbol.toStringTag]() {
       return 'User'; // The string tag description
   },
   toString() {
       return `${this.firstname} ${this.lastname}`;
   }
};

console.log(user[Symbol.toStringTag]); // -> "User"
console.log(user.toString()); // -> "John Doe"
```

All the code examples are in the following CodePen:

<iframe height="265" style="width: 100%;" scrolling="no" title="Symbol.stringTag" src="https://codepen.io/cherifGsoul/embed/KKWPWpE?height=265&theme-id=light&default-tab=js,result" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href='https://codepen.io/cherifGsoul/pen/KKWPWpE'>Symbol.stringTag</a> by Mohamed Cherif Bouchelaghem
  (<a href='https://codepen.io/cherifGsoul'>@cherifGsoul</a>) on <a href='https://codepen.io'>CodePen</a>.
</iframe>

I hope you find this article useful and helpful, let me know your thoughts in the comments below.