--- description: 'Require both operands of addition to be the same type and be `bigint`, `number`, or `string`.' --- > 🛑 This file is source code, not the primary documentation location! 🛑 > > See **https://typescript-eslint.io/rules/restrict-plus-operands** for documentation. TypeScript allows `+` adding together two values of any type(s). However, adding values that are not the same type and/or are not the same primitive type is often a sign of programmer error. This rule reports when a `+` operation combines two values of different types, or a type that is not `bigint`, `number`, or `string`. ## Examples ### ❌ Incorrect ```ts let foo = '5.5' + 5; let foo = 1n + 1; ``` ### ✅ Correct ```ts let foo = parseInt('5.5', 10) + 10; let foo = 1n + 1n; ``` ## Options :::caution We generally recommend against using these options, as they limit which varieties of incorrect `+` usage can be checked. This in turn severely limits the validation that the rule can do to ensure that resulting strings and numbers are correct. Safer alternatives to using the `allow*` options include: - Using variadic forms of logging APIs to avoid needing to `+` values. ```ts // Remove this line console.log('The result is ' + true); // Add this line console.log('The result is', true); ``` - Using `.toFixed()` to coerce numbers to well-formed string representations: ```ts const number = 1.123456789; const result = 'The number is ' + number.toFixed(2); // result === 'The number is 1.12' ``` - Calling `.toString()` on other types to mark explicit and intentional string coercion: ```ts const arg = '11'; const regex = /[0-9]/; const result = 'The result of ' + regex.toString() + '.test("' + arg + '") is ' + regex.test(arg).toString(); // result === 'The result of /[0-9]/.test("11") is true' ``` ::: ### `allowAny` Examples of code for this rule with `{ allowAny: true }`: #### ❌ Incorrect ```ts option='{ "allowAny": true }' let fn = (a: number, b: []) => a + b; let fn = (a: string, b: []) => a + b; ``` #### ✅ Correct ```ts option='{ "allowAny": true }' let fn = (a: number, b: any) => a + b; let fn = (a: string, b: any) => a + b; ``` ### `allowBoolean` Examples of code for this rule with `{ allowBoolean: true }`: #### ❌ Incorrect ```ts option='{ "allowBoolean": true }' let fn = (a: number, b: unknown) => a + b; let fn = (a: string, b: unknown) => a + b; ``` #### ✅ Correct ```ts option='{ "allowBoolean": true }' let fn = (a: number, b: boolean) => a + b; let fn = (a: string, b: boolean) => a + b; ``` ### `allowNullish` Examples of code for this rule with `{ allowNullish: true }`: #### ❌ Incorrect ```ts option='{ "allowNullish": true }' let fn = (a: number, b: unknown) => a + b; let fn = (a: number, b: never) => a + b; let fn = (a: string, b: unknown) => a + b; let fn = (a: string, b: never) => a + b; ``` #### ✅ Correct ```ts option='{ "allowNullish": true }' let fn = (a: number, b: undefined) => a + b; let fn = (a: number, b: null) => a + b; let fn = (a: string, b: undefined) => a + b; let fn = (a: string, b: null) => a + b; ``` ### `allowNumberAndString` Examples of code for this rule with `{ allowNumberAndString: true }`: #### ❌ Incorrect ```ts option='{ "allowNumberAndString": true }' let fn = (a: number, b: unknown) => a + b; let fn = (a: number, b: never) => a + b; ``` #### ✅ Correct ```ts option='{ "allowNumberAndString": true }' let fn = (a: number, b: string) => a + b; let fn = (a: number, b: number | string) => a + b; ``` ### `allowRegExp` Examples of code for this rule with `{ allowRegExp: true }`: #### ❌ Incorrect ```ts option='{ "allowRegExp": true }' let fn = (a: number, b: RegExp) => a + b; ``` #### ✅ Correct ```ts option='{ "allowRegExp": true }' let fn = (a: string, b: RegExp) => a + b; ``` ### `skipCompoundAssignments` Examples of code for this rule with `{ skipCompoundAssignments: false }`: #### ❌ Incorrect ```ts option='{ "skipCompoundAssignments": true }' let foo: string | undefined; foo += 'some data'; let bar: string = ''; bar += 0; ``` #### ✅ Correct ```ts option='{ "skipCompoundAssignments": true }' let foo: number = 0; foo += 1; let bar = ''; bar += 'test'; ``` ## When 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 - [`no-base-to-string`](./no-base-to-string.md) - [`restrict-template-expressions`](./restrict-template-expressions.md) ## Further Reading - [`Object.prototype.toString()` MDN documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString)