When calling toString() or coercing into a string an object that doesn’t implement its own toString method, it returns [object Object] which is often not what was intended.

Why is this an issue?

When using an object in a string context, a developer wants to get the string representation of the state of an object, so obtaining [object Object] is probably not the intended behaviour and might even denote a bug.

How to fix it

You can simply define a toString() method for the object or class.

Code examples

Noncompliant code example

class Foo {};
const foo = new Foo();

foo + ''; // Noncompliant - evaluates to "[object Object]"
`Foo: ${foo}`; // Noncompliant - evaluates to "Foo: [object Object]"
foo.toString(); // Noncompliant - evaluates to "[object Object]"

Compliant solution

class Foo {
  toString() {
    return 'Foo';
  }
}
const foo = new Foo();

foo + '';
`Foo: ${foo}`;
foo.toString();

Noncompliant code example

const foo = {};
foo + ''; // Noncompliant - evaluates to "[object Object]"
`Foo: ${foo}`; // Noncompliant - evaluates to "Foo: [object Object]"
foo.toString(); // Noncompliant - evaluates to "[object Object]"

Compliant solution

const foo = {
  toString: () => {
    return 'Foo';
  }
}
foo + '';
`Foo: ${foo}`;
foo.toString();

Exceptions

This rule does not raise an issue when a direct toString() call is the first statement in a branch that checks the same object against Object.prototype.toString.

function render(value) {
  if (value.toString !== Object.prototype.toString) {
    return value.toString();
  }

  return undefined;
}

function renderOrFallback(value, fallback) {
  if (value.toString === Object.prototype.toString) {
    return fallback;
  } else {
    return value.toString();
  }
}

This rule also does not raise an issue when the result of a direct toString() call is stored in a constant, immediately checked against [object Object], and only the non-default result is used. The same applies when the default result is handled in the if branch and the validated value is used in else.

function pretty(data) {
  if (data && typeof data === 'object' && typeof data.toString === 'function') {
    const rendered = data.toString();
    if (rendered !== '[object Object]') {
      return rendered;
    }
  }

  return data;
}

Resources

Documentation