no-base-to-string
Require
.toString()
and.toLocaleString()
to only be called on objects which provide useful information when stringified.
Extending "plugin:@typescript-eslint/recommended-type-checked"
in an ESLint configuration enables this rule.
This rule requires type information to run.
JavaScript will call toString()
on an object when it is converted to a string, such as when concatenated with a string (expr + ''
), when interpolated into template literals (${expr}
), or when passed as an argument to the String constructor (String(expr)
).
The default Object .toString()
and toLocaleString()
use the format "[object Object]"
, which is often not what was intended.
This rule reports on stringified values that aren't primitives and don't define a more useful .toString()
or toLocaleString()
method.
Note that
Function
provides its own.toString()
andtoLocaleString()
that return the function's code. Functions are not flagged by this rule.
- Flat Config
- Legacy Config
export default tseslint.config({
rules: {
"@typescript-eslint/no-base-to-string": "error"
}
});
module.exports = {
"rules": {
"@typescript-eslint/no-base-to-string": "error"
}
};
Try this rule in the playground ↗
Examples
- ❌ Incorrect
- ✅ Correct
// Passing an object or class instance to string concatenation:
'' + {};
class MyClass {}
const value = new MyClass();
value + '';
// Interpolation and manual .toString() and `toLocaleString()` calls too:
`Value: ${value}`;
String({});
({}).toString();
({}).toLocaleString();
// Stringifying objects or instances in an array with the `Array.prototype.join`.
[{}, new MyClass()].join('');
Open in Playground// These types all have useful .toString() and `toLocaleString()` methods
'Text' + true;
`Value: ${123}`;
`Arrays too: ${[1, 2, 3]}`;
(() => {}).toString();
String(42);
(() => {}).toLocaleString();
// Defining a custom .toString class is considered acceptable
class CustomToString {
toString() {
return 'Hello, world!';
}
}
`Value: ${new CustomToString()}`;
const literalWithToString = {
toString: () => 'Hello, world!',
};
`Value: ${literalWithToString}`;
Open in PlaygroundAlternatives
Consider using JSON.stringify
when you want to convert non-primitive things to string for logging, debugging, etc.
declare const o: object;
const errorMessage = 'Found unexpected value: ' + JSON.stringify(o);
Options
This rule accepts the following options:
type Options = [
{
/** Stringified regular expressions of type names to ignore. */
ignoredTypeNames?: string[];
},
];
const defaultOptions: Options = [
{ ignoredTypeNames: ['Error', 'RegExp', 'URL', 'URLSearchParams'] },
];
ignoredTypeNames
Stringified regular expressions of type names to ignore. Default: ["Error","RegExp","URL","URLSearchParams"]
.
This is useful for types missing toString()
or toLocaleString()
(but actually has toString()
or toLocaleString()
).
There are some types missing toString()
or toLocaleString()
in old versions of TypeScript, like RegExp
, URL
, URLSearchParams
etc.
The following patterns are considered correct with the default options { ignoredTypeNames: ["RegExp"] }
:
`${/regex/}`;
'' + /regex/;
/regex/.toString();
let value = /regex/;
value.toString();
let text = `${value}`;
String(/regex/);
Open in PlaygroundWhen Not To Use It
If you don't mind a risk of "[object Object]"
or incorrect type coercions in your values, then you will not need this rule.
Related To
Further Reading
Object.prototype.toString()
MDN documentationObject.prototype.toLocaleString()
MDN documentation- Microsoft/TypeScript Add missing toString declarations for base types that have them
Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.
See Troubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.