diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index 0917484ea02..0edf8a37d20 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -70,6 +70,11 @@ export default util.createRule({ return types.every(value => value === types[0]) ? types[0] : 'invalid'; } + if (type.isIntersection()) { + const types = type.types.map(getBaseTypeOfLiteralType); + return types.some(value => value === 'string') ? 'string' : 'invalid'; + } + const stringType = typeChecker.typeToString(type); if ( diff --git a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts index 43682806f59..daa02fa46d9 100644 --- a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts +++ b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts @@ -90,6 +90,26 @@ function foo(a: T) { function foo(a: T) { return a + 1; } + `, + ` +declare const a: {} & string; +declare const b: string; +const x = a + b; + `, + ` +declare const a: unknown & string; +declare const b: string; +const x = a + b; + `, + ` +declare const a: string & string; +declare const b: string; +const x = a + b; + `, + ` +declare const a: 'string literal' & string; +declare const b: string; +const x = a + b; `, { code: ` @@ -411,6 +431,104 @@ function foo(a: T) { }, ], }, + { + code: ` + declare const a: boolean & string; + declare const b: string; + const x = a + b; + `, + errors: [ + { + messageId: 'notStrings', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: number & string; + declare const b: string; + const x = a + b; + `, + errors: [ + { + messageId: 'notStrings', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: symbol & string; + declare const b: string; + const x = a + b; + `, + errors: [ + { + messageId: 'notStrings', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: object & string; + declare const b: string; + const x = a + b; + `, + errors: [ + { + messageId: 'notStrings', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: never & string; + declare const b: string; + const x = a + b; + `, + errors: [ + { + messageId: 'notStrings', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: any & string; + declare const b: string; + const x = a + b; + `, + errors: [ + { + messageId: 'notStrings', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: { a: 1 } & { b: 2 }; + declare const b: string; + const x = a + b; + `, + errors: [ + { + messageId: 'notStrings', + line: 4, + column: 19, + }, + ], + }, { code: ` let foo: string | undefined;