From 96f5d1b7ce971ff17ab92adb37b6bd75c77b7dff Mon Sep 17 00:00:00 2001 From: Veda Date: Sun, 28 Jul 2019 00:01:50 +0530 Subject: [PATCH 1/4] fix: add bigint support to restrict-plus-operand rule --- src/rules/restrictPlusOperandsRule.ts | 9 ++- .../rules/restrict-plus-operands/test.ts.lint | 68 +++++++++++++------ .../restrict-plus-operands/tsconfig.json | 3 +- 3 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/rules/restrictPlusOperandsRule.ts b/src/rules/restrictPlusOperandsRule.ts index 5b34e6a5cce..a4cc39764a2 100644 --- a/src/rules/restrictPlusOperandsRule.ts +++ b/src/rules/restrictPlusOperandsRule.ts @@ -36,7 +36,7 @@ export class Rule extends Lint.Rules.TypedRule { /* tslint:enable:object-literal-sort-keys */ public static INVALID_TYPES_ERROR = - "Operands of '+' operation must either be both strings or both numbers"; + "Operands of '+' operation must either be both strings or both numbers or both bigints"; public static SUGGEST_TEMPLATE_LITERALS = ". Consider using template literals."; public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] { @@ -85,7 +85,7 @@ function getTypeString(tc: ts.TypeChecker, node: ts.Node, type: ts.Type) { return typeString; } -function getBaseTypeOfLiteralType(type: ts.Type): "string" | "number" | "invalid" { +function getBaseTypeOfLiteralType(type: ts.Type): "string" | "number" | "bigint" | "invalid" { if ( isTypeFlagSet(type, ts.TypeFlags.StringLiteral) || isTypeFlagSet(type, ts.TypeFlags.String) @@ -96,6 +96,11 @@ function getBaseTypeOfLiteralType(type: ts.Type): "string" | "number" | "invalid isTypeFlagSet(type, ts.TypeFlags.Number) ) { return "number"; + } else if ( + isTypeFlagSet(type, ts.TypeFlags.BigIntLiteral) || + isTypeFlagSet(type, ts.TypeFlags.BigInt) + ) { + return "bigint"; } else if (isUnionType(type) && !isTypeFlagSet(type, ts.TypeFlags.Enum)) { const types = type.types.map(getBaseTypeOfLiteralType); return allSame(types) ? types[0] : "invalid"; diff --git a/test/rules/restrict-plus-operands/test.ts.lint b/test/rules/restrict-plus-operands/test.ts.lint index 4899d42ced7..1736b2644b1 100644 --- a/test/rules/restrict-plus-operands/test.ts.lint +++ b/test/rules/restrict-plus-operands/test.ts.lint @@ -1,54 +1,58 @@ // aliases for number type MyNumber = number; type MyString = string; -interface NumberStringPair { +type MyBigInt = bigint; +interface NumberStringBigint { first: MyNumber, - second: MyString + second: MyString, + third: MyBigInt } var x = 5; var y = "10"; var z = 8.2; var w = "6.5"; -var pair: NumberStringPair = { +var bigintVar = BigInt(200); +var pair: NumberStringBigint = { first: 5, - second: "10" + second: "10", + third: BigInt(100), }; // bad var bad1 = 5 + "10"; - ~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found 5 + "10". Consider using template literals.] + ~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found 5 + "10". Consider using template literals.] var bad2 = [] + 5; - ~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found [] + 5] + ~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found [] + 5] var bad3 = [] + {}; - ~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found [] + {}] + ~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found [] + {}] var bad4 = [] + []; - ~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found [] + []] + ~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found [] + []] var bad4 = 5 + []; - ~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found 5 + []] + ~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found 5 + []] var bad5 = "5" + {}; - ~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found "5" + {}. Consider using template literals.] + ~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found "5" + {}. Consider using template literals.] var bad6 = 5.5 + "5"; - ~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found 5.5 + "5". Consider using template literals.] + ~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found 5.5 + "5". Consider using template literals.] var bad7 = "5.5" + 5; - ~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found "5.5" + 5. Consider using template literals.] + ~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found "5.5" + 5. Consider using template literals.] var bad8 = x + y; - ~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found number + string. Consider using template literals.] + ~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found number + string. Consider using template literals.] var bad9 = y + x; - ~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found string + number. Consider using template literals.] + ~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found string + number. Consider using template literals.] var bad10 = x + {}; - ~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found number + {}] + ~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found number + {}] var bad11 = [] + y; - ~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found [] + string. Consider using template literals.] + ~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found [] + string. Consider using template literals.] var bad12 = pair.first + "10"; - ~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found number + "10". Consider using template literals.] + ~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found number + "10". Consider using template literals.] var bad13 = 5 + pair.second; - ~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found 5 + string. Consider using template literals.] + ~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found 5 + string. Consider using template literals.] var bad14 = pair + pair; - ~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found NumberStringPair + NumberStringPair] + ~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found NumberStringBigint + NumberStringBigint] var anyTyped: any = 5; var bad15 = anyTyped + 12; - ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers, but found any + 12] + ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found any + 12] // good var good1 = 5 + 10; @@ -63,6 +67,30 @@ var good8 = "5.5" + pair.second; var good9 = ("5.5" as MyString) + pair.second; const good10 = 'hello' + (someBoolean ? 'a' : 'b') + (() => someBoolean ? 'c' : 'd')() + 'e'; +var anyVar: any = 200; + +const bigIntPassA = BigInt(1) + BigInt(2); +const bigIntPassB = BigInt(1) + 100n; +const bigIntFailA = BigInt(1) + 2; + ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + 2] +const bigIntFailB = BigInt(1) + "failureString"; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + "failureString". Consider using template literals.] + +const bigIntFailC = bigintVar + x; + ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + number] +const bigIntFailD = y + bigintVar; + ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found string + bigint. Consider using template literals.] +const bigIntFailE = bigintVar + anyVar; + ~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + any] + +const bigIntFailF = pair.first + pair.third; + ~~~~~~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found number + bigint] +const bigIntFailG = pair.third + pair.second; + ~~~~~~~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + string. Consider using template literals.] +const bigIntFailH = bigintVar + []; + ~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + []] +const bigIntFailI = bigintVar + {}; + ~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + {}] // don't check other binary expressions const balls = true; balls === true; diff --git a/test/rules/restrict-plus-operands/tsconfig.json b/test/rules/restrict-plus-operands/tsconfig.json index 744a66c893a..09d960629bb 100644 --- a/test/rules/restrict-plus-operands/tsconfig.json +++ b/test/rules/restrict-plus-operands/tsconfig.json @@ -1,5 +1,6 @@ { "compilerOptions": { - "module": "commonjs" + "module": "commonjs", + "target": "esnext" } } From 273eff1a0269e3852f40a0587505ec609dd574cb Mon Sep 17 00:00:00 2001 From: Veda Date: Sun, 28 Jul 2019 00:26:11 +0530 Subject: [PATCH 2/4] remove module: commonJs --- test/rules/restrict-plus-operands/tsconfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/test/rules/restrict-plus-operands/tsconfig.json b/test/rules/restrict-plus-operands/tsconfig.json index 09d960629bb..0d58d115f70 100644 --- a/test/rules/restrict-plus-operands/tsconfig.json +++ b/test/rules/restrict-plus-operands/tsconfig.json @@ -1,6 +1,5 @@ { "compilerOptions": { - "module": "commonjs", "target": "esnext" } } From 8b871b61ff9572cc11dbcd92dbb22ee7543673f3 Mon Sep 17 00:00:00 2001 From: Veda Date: Sun, 28 Jul 2019 00:44:53 +0530 Subject: [PATCH 3/4] add bigint tests to a separate tsconfig --- .../{ => default}/test.ts.lint | 38 +++-------------- .../default/tsconfig.json | 5 +++ .../{ => default}/tslint.json | 0 .../esnext-bigint/test.ts.lint | 42 +++++++++++++++++++ .../{ => esnext-bigint}/tsconfig.json | 0 .../esnext-bigint/tslint.json | 5 +++ 6 files changed, 57 insertions(+), 33 deletions(-) rename test/rules/restrict-plus-operands/{ => default}/test.ts.lint (61%) create mode 100644 test/rules/restrict-plus-operands/default/tsconfig.json rename test/rules/restrict-plus-operands/{ => default}/tslint.json (100%) create mode 100644 test/rules/restrict-plus-operands/esnext-bigint/test.ts.lint rename test/rules/restrict-plus-operands/{ => esnext-bigint}/tsconfig.json (100%) create mode 100644 test/rules/restrict-plus-operands/esnext-bigint/tslint.json diff --git a/test/rules/restrict-plus-operands/test.ts.lint b/test/rules/restrict-plus-operands/default/test.ts.lint similarity index 61% rename from test/rules/restrict-plus-operands/test.ts.lint rename to test/rules/restrict-plus-operands/default/test.ts.lint index 1736b2644b1..f1c604d3efe 100644 --- a/test/rules/restrict-plus-operands/test.ts.lint +++ b/test/rules/restrict-plus-operands/default/test.ts.lint @@ -1,22 +1,18 @@ // aliases for number type MyNumber = number; type MyString = string; -type MyBigInt = bigint; -interface NumberStringBigint { +interface NumberStringPair { first: MyNumber, - second: MyString, - third: MyBigInt + second: MyString } var x = 5; var y = "10"; var z = 8.2; var w = "6.5"; -var bigintVar = BigInt(200); -var pair: NumberStringBigint = { +var pair: NumberStringPair = { first: 5, - second: "10", - third: BigInt(100), + second: "10" }; // bad @@ -49,7 +45,7 @@ var bad12 = pair.first + "10"; var bad13 = 5 + pair.second; ~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found 5 + string. Consider using template literals.] var bad14 = pair + pair; - ~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found NumberStringBigint + NumberStringBigint] + ~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found NumberStringPair + NumberStringPair] var anyTyped: any = 5; var bad15 = anyTyped + 12; ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found any + 12] @@ -67,30 +63,6 @@ var good8 = "5.5" + pair.second; var good9 = ("5.5" as MyString) + pair.second; const good10 = 'hello' + (someBoolean ? 'a' : 'b') + (() => someBoolean ? 'c' : 'd')() + 'e'; -var anyVar: any = 200; - -const bigIntPassA = BigInt(1) + BigInt(2); -const bigIntPassB = BigInt(1) + 100n; -const bigIntFailA = BigInt(1) + 2; - ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + 2] -const bigIntFailB = BigInt(1) + "failureString"; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + "failureString". Consider using template literals.] - -const bigIntFailC = bigintVar + x; - ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + number] -const bigIntFailD = y + bigintVar; - ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found string + bigint. Consider using template literals.] -const bigIntFailE = bigintVar + anyVar; - ~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + any] - -const bigIntFailF = pair.first + pair.third; - ~~~~~~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found number + bigint] -const bigIntFailG = pair.third + pair.second; - ~~~~~~~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + string. Consider using template literals.] -const bigIntFailH = bigintVar + []; - ~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + []] -const bigIntFailI = bigintVar + {}; - ~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + {}] // don't check other binary expressions const balls = true; balls === true; diff --git a/test/rules/restrict-plus-operands/default/tsconfig.json b/test/rules/restrict-plus-operands/default/tsconfig.json new file mode 100644 index 00000000000..744a66c893a --- /dev/null +++ b/test/rules/restrict-plus-operands/default/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "module": "commonjs" + } +} diff --git a/test/rules/restrict-plus-operands/tslint.json b/test/rules/restrict-plus-operands/default/tslint.json similarity index 100% rename from test/rules/restrict-plus-operands/tslint.json rename to test/rules/restrict-plus-operands/default/tslint.json diff --git a/test/rules/restrict-plus-operands/esnext-bigint/test.ts.lint b/test/rules/restrict-plus-operands/esnext-bigint/test.ts.lint new file mode 100644 index 00000000000..75d761e81ca --- /dev/null +++ b/test/rules/restrict-plus-operands/esnext-bigint/test.ts.lint @@ -0,0 +1,42 @@ +// aliases for number +type MyNumber = number; +type MyString = string; +type MyBigInt = bigint; +interface NumberStringBigint { + first: MyNumber, + second: MyString, + third: MyBigInt +} + +var x = 5; +var y = "10"; +var bigintVar = BigInt(200); +var anyVar: any = 200; +var pair: NumberStringBigint = { + first: 5, first: 5, + second: "10" second: "10", + third: BigInt(100), +}; + +const bigIntPassA = BigInt(1) + BigInt(2); +const bigIntPassB = BigInt(1) + 100n; +const bigIntFailA = BigInt(1) + 2; + ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + 2] +const bigIntFailB = BigInt(1) + "failureString"; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + "failureString". Consider using template literals.] + +const bigIntFailC = bigintVar + x; + ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + number] +const bigIntFailD = y + bigintVar; + ~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found string + bigint. Consider using template literals.] +const bigIntFailE = bigintVar + anyVar; + ~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + any] + +const bigIntFailF = pair.first + pair.third; + ~~~~~~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found number + bigint] +const bigIntFailG = pair.third + pair.second; + ~~~~~~~~~~~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + string. Consider using template literals.] +const bigIntFailH = bigintVar + []; + ~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + []] +const bigIntFailI = bigintVar + {}; + ~~~~~~~~~~~~~~ [Operands of '+' operation must either be both strings or both numbers or both bigints, but found bigint + {}] diff --git a/test/rules/restrict-plus-operands/tsconfig.json b/test/rules/restrict-plus-operands/esnext-bigint/tsconfig.json similarity index 100% rename from test/rules/restrict-plus-operands/tsconfig.json rename to test/rules/restrict-plus-operands/esnext-bigint/tsconfig.json diff --git a/test/rules/restrict-plus-operands/esnext-bigint/tslint.json b/test/rules/restrict-plus-operands/esnext-bigint/tslint.json new file mode 100644 index 00000000000..e5801e9ba40 --- /dev/null +++ b/test/rules/restrict-plus-operands/esnext-bigint/tslint.json @@ -0,0 +1,5 @@ +{ + "rules": { + "restrict-plus-operands": true + } +} From 0bf680ce999a8a0601b9934cd538bdf0f292772d Mon Sep 17 00:00:00 2001 From: Veda Date: Sun, 28 Jul 2019 00:57:01 +0530 Subject: [PATCH 4/4] add typescript >=3.2.0 flag to bignint test --- test/rules/restrict-plus-operands/esnext-bigint/test.ts.lint | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/rules/restrict-plus-operands/esnext-bigint/test.ts.lint b/test/rules/restrict-plus-operands/esnext-bigint/test.ts.lint index 75d761e81ca..b8ddc80558c 100644 --- a/test/rules/restrict-plus-operands/esnext-bigint/test.ts.lint +++ b/test/rules/restrict-plus-operands/esnext-bigint/test.ts.lint @@ -1,4 +1,4 @@ -// aliases for number +[typescript]: >= 3.2.0 type MyNumber = number; type MyString = string; type MyBigInt = bigint;