From 52b53b8cc753d09b7802eddd027aa2dea15a9351 Mon Sep 17 00:00:00 2001 From: Leon Si Date: Fri, 8 Apr 2022 08:31:11 -0400 Subject: [PATCH 1/3] feat: support number and bigint intersections in restrict-plus-operands rule --- .../src/rules/restrict-plus-operands.ts | 7 +- .../rules/restrict-plus-operands.test.ts | 198 +++++++++++++++++- 2 files changed, 202 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index d126dc42bfb0..a7309928b541 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -88,7 +88,12 @@ 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 ec14f26db7b3..f8ecb1d51084 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; `, ` @@ -564,12 +604,166 @@ function foo(a: T) { { code: ` declare const a: { a: 1 } & { b: 2 }; - declare const b: string; + declare const b: number; const x = a + b; `, errors: [ { - messageId: 'notStrings', + messageId: 'notNumbers', + line: 4, + column: 19, + }, + ], + }, + { + 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: 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, }, From cc2423d03254db545eb56a9118e50cbd1975f667 Mon Sep 17 00:00:00 2001 From: Leon Si Date: Fri, 8 Apr 2022 08:57:49 -0400 Subject: [PATCH 2/3] fix: tests --- .../rules/restrict-plus-operands.test.ts | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) 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 f8ecb1d51084..72621ad0efa9 100644 --- a/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts +++ b/packages/eslint-plugin/tests/rules/restrict-plus-operands.test.ts @@ -604,12 +604,12 @@ function foo(a: T) { { code: ` declare const a: { a: 1 } & { b: 2 }; - declare const b: number; + declare const b: string; const x = a + b; `, errors: [ { - messageId: 'notNumbers', + messageId: 'notStrings', line: 4, column: 19, }, @@ -685,6 +685,20 @@ function foo(a: T) { }, ], }, + { + 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; @@ -769,6 +783,20 @@ function foo(a: T) { }, ], }, + { + 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; From e86b7f0007326877093400ccd3bc482328e79308 Mon Sep 17 00:00:00 2001 From: Leon Si Date: Fri, 8 Apr 2022 09:33:42 -0400 Subject: [PATCH 3/3] style: formatting --- .../src/rules/restrict-plus-operands.ts | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts index a7309928b541..6d2052b6be7e 100644 --- a/packages/eslint-plugin/src/rules/restrict-plus-operands.ts +++ b/packages/eslint-plugin/src/rules/restrict-plus-operands.ts @@ -89,9 +89,17 @@ export default util.createRule({ if (type.isIntersection()) { const types = type.types.map(getBaseTypeOfLiteralType); - if (types.some(value => value === 'string')) return 'string'; - if (types.some(value => value === 'number')) return 'number'; - if (types.some(value => value === 'bigint')) return 'bigint'; + 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'; }