+ accepts anything. An object or an array is turned into a string first, so [] + 5 is "5" and "User: " + user is "User: [object Object]". A number plus a bigint throws a TypeError when it runs.
By default this rule reports objects, arrays, symbols, unknown, never, and a number mixed with a bigint. Turn the allow options off to make it stricter.
bun lint --type-aware turns this rule on in TypeScript files.
Configure
Off by default. This rule needs types, so turning it on makes bun lint type check your code first.
[lint.rules]
"@typescript-eslint/restrict-plus-operands" = "error" # or "warn"
Every option, set to its default:
[lint.rules]
"@typescript-eslint/restrict-plus-operands" = ["error", {
allowAny = true,
allowBoolean = true,
allowNullish = true,
allowNumberAndString = true,
allowRegExp = true,
skipCompoundAssignments = false,
}]
Examples
Reported:
function describe(user: { name: string }, tags: string[], size: bigint) {
const label = "User: " + user;
const list = "Tags: " + tags;
const next = size + 1;
}
Not reported:
function describe(user: { name: string }, tags: string[], size: bigint) {
const label = "User: " + user.name;
const list = "Tags: " + tags.join(", ");
const next = size + 1n;
}
Options
| Option | Default | What it does |
|---|---|---|
allowAny | true | Allow an operand of type any. |
allowBoolean | true | Allow a boolean operand. |
allowNullish | true | Allow an operand that can be null or undefined. |
allowNumberAndString | true | Allow adding a number or a bigint to a string. |
allowRegExp | true | Allow a RegExp operand. A RegExp plus a number is always reported. |
skipCompoundAssignments | false | Don't check +=. |
With all the allow options off, both sides must have the same type:
function report(count: number, done: boolean, name?: string) {
const a = "Items: " + count;
const b = "Done: " + done;
const c = "Name: " + name;
}
+= is checked like +. This is reported unless skipCompoundAssignments is on:
let log = "";
log += ["started"];