From 19c600a3dd485669cb87ae8f81b010e65eee1df8 Mon Sep 17 00:00:00 2001 From: Leon Si Date: Fri, 8 Apr 2022 17:14:44 -0400 Subject: [PATCH] feat(eslint-plugin): add support for valid number and bigint intersections in restrict-plus-operands rule (#4795) * feat: support number and bigint intersections in restrict-plus-operands rule * fix: tests * style: formatting --- .../src/rules/restrict-plus-operands.ts | 15 +- .../rules/restrict-plus-operands.test.ts | 222 ++++++++++++++++++ 2 files changed, 236 insertions(+), 1 deletion(-) diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index d126dc42bfb..6d2052b6be7 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -88,7 +88,20 @@ export default util.createRule({ if (type.isIntersection()) { const types = type.types.map(getBaseTypeOfLiteralType); - return types.some(value => value === 'string') ? 'string' : 'invalid'; + + if (types.some(value => value === 'string')) { + return 'string'; + } + + if (types.some(value => value === 'number')) { + return 'number'; + } + + if (types.some(value => value === 'bigint')) { + return 'bigint'; + } + + return 'invalid'; } const stringType = typeChecker.typeToString(type); 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 ec14f26db7b..72621ad0efa 100644 --- a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts +++ b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts @@ -109,6 +109,46 @@ const x = a + b; ` declare const a: 'string literal' & string; declare const b: string; +const x = a + b; + `, + ` +declare const a: {} & number; +declare const b: number; +const x = a + b; + `, + ` +declare const a: unknown & number; +declare const b: number; +const x = a + b; + `, + ` +declare const a: number & number; +declare const b: number; +const x = a + b; + `, + ` +declare const a: 42 & number; +declare const b: number; +const x = a + b; + `, + ` +declare const a: {} & bigint; +declare const b: bigint; +const x = a + b; + `, + ` +declare const a: unknown & bigint; +declare const b: bigint; +const x = a + b; + `, + ` +declare const a: bigint & bigint; +declare const b: bigint; +const x = a + b; + `, + ` +declare const a: 42n & bigint; +declare const b: bigint; const x = a + b; `, ` @@ -575,6 +615,188 @@ function foo(a: T) { }, ], }, + { + code: ` + declare const a: boolean & number; + declare const b: number; + const x = a + b; + `, + errors: [ + { + messageId: 'notNumbers', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: symbol & number; + declare const b: number; + const x = a + b; + `, + errors: [ + { + messageId: 'notNumbers', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: object & number; + declare const b: number; + const x = a + b; + `, + errors: [ + { + messageId: 'notNumbers', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: never & number; + declare const b: number; + const x = a + b; + `, + errors: [ + { + messageId: 'notNumbers', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: any & number; + declare const b: number; + const x = a + b; + `, + errors: [ + { + messageId: 'notValidAnys', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: { a: 1 } & { b: 2 }; + declare const b: number; + const x = a + b; + `, + errors: [ + { + messageId: 'notNumbers', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: boolean & bigint; + declare const b: bigint; + const x = a + b; + `, + errors: [ + { + messageId: 'notBigInts', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: number & bigint; + declare const b: bigint; + const x = a + b; + `, + errors: [ + { + messageId: 'notBigInts', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: symbol & bigint; + declare const b: bigint; + const x = a + b; + `, + errors: [ + { + messageId: 'notBigInts', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: object & bigint; + declare const b: bigint; + const x = a + b; + `, + errors: [ + { + messageId: 'notBigInts', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: never & bigint; + declare const b: bigint; + const x = a + b; + `, + errors: [ + { + messageId: 'notBigInts', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: any & bigint; + declare const b: bigint; + const x = a + b; + `, + errors: [ + { + messageId: 'notValidAnys', + line: 4, + column: 19, + }, + ], + }, + { + code: ` + declare const a: { a: 1 } & { b: 2 }; + declare const b: bigint; + const x = a + b; + `, + errors: [ + { + messageId: 'notBigInts', + line: 4, + column: 19, + }, + ], + }, { code: ` let foo: string | undefined;