From e301cfe58c62454c06d3e6b173295296f2cd6857 Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders Date: Thu, 10 Nov 2016 14:29:48 -0800 Subject: [PATCH] Raise literal type to its base in a comparison Similar to ===, except that it always applies, even when comparing two literals. --- src/compiler/checker.ts | 2 + .../relationalOperatorComparable.errors.txt | 40 +++++++++++++++++++ .../reference/relationalOperatorComparable.js | 34 ++++++++++++++++ .../compiler/relationalOperatorComparable.ts | 15 +++++++ 4 files changed, 91 insertions(+) create mode 100644 tests/baselines/reference/relationalOperatorComparable.errors.txt create mode 100644 tests/baselines/reference/relationalOperatorComparable.js create mode 100644 tests/cases/compiler/relationalOperatorComparable.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1510979305b..e119c965f0f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14241,6 +14241,8 @@ namespace ts { case SyntaxKind.LessThanEqualsToken: case SyntaxKind.GreaterThanEqualsToken: if (checkForDisallowedESSymbolOperand(operator)) { + leftType = getBaseTypeOfLiteralType(leftType); + rightType = getBaseTypeOfLiteralType(rightType); if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) { reportOperatorError(); } diff --git a/tests/baselines/reference/relationalOperatorComparable.errors.txt b/tests/baselines/reference/relationalOperatorComparable.errors.txt new file mode 100644 index 00000000000..bc48eaf92c0 --- /dev/null +++ b/tests/baselines/reference/relationalOperatorComparable.errors.txt @@ -0,0 +1,40 @@ +tests/cases/compiler/relationalOperatorComparable.ts(5,14): error TS2365: Operator '<' cannot be applied to types 'number' and 'boolean'. +tests/cases/compiler/relationalOperatorComparable.ts(6,14): error TS2365: Operator '<=' cannot be applied to types 'number' and 'boolean'. +tests/cases/compiler/relationalOperatorComparable.ts(7,14): error TS2365: Operator '>=' cannot be applied to types 'number' and 'boolean'. +tests/cases/compiler/relationalOperatorComparable.ts(8,14): error TS2365: Operator '>' cannot be applied to types 'number' and 'boolean'. +tests/cases/compiler/relationalOperatorComparable.ts(9,14): error TS2365: Operator '<' cannot be applied to types 'boolean' and 'number'. +tests/cases/compiler/relationalOperatorComparable.ts(10,14): error TS2365: Operator '<' cannot be applied to types 'boolean' and 'number'. +tests/cases/compiler/relationalOperatorComparable.ts(11,14): error TS2365: Operator '<' cannot be applied to types 'string' and 'number'. + + +==== tests/cases/compiler/relationalOperatorComparable.ts (7 errors) ==== + function f(onethree: 1 | 3, two: 2) { + const t = true; + const f = false; + let a1 = onethree < two; // ok + let a2 = onethree < true; // error, number and boolean + ~~~~~~~~~~~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'boolean'. + let a3 = onethree <= false; // error, number and boolean + ~~~~~~~~~~~~~~~~~ +!!! error TS2365: Operator '<=' cannot be applied to types 'number' and 'boolean'. + let a4 = onethree >= t; // error, number and boolean + ~~~~~~~~~~~~~ +!!! error TS2365: Operator '>=' cannot be applied to types 'number' and 'boolean'. + let a5 = onethree > f; // error, number and boolean + ~~~~~~~~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'number' and 'boolean'. + let a6 = true < onethree; // error, boolean and number + ~~~~~~~~~~~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types 'boolean' and 'number'. + let a7 = false < two; // error, boolean and number + ~~~~~~~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types 'boolean' and 'number'. + let a8 = 'foo' < onethree; // error, string and number + ~~~~~~~~~~~~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types 'string' and 'number'. + let a9 = onethree < 1; // ok + let a10 = 1 < two; // ok + let a11 = 2 < 1; // ok + } + \ No newline at end of file diff --git a/tests/baselines/reference/relationalOperatorComparable.js b/tests/baselines/reference/relationalOperatorComparable.js new file mode 100644 index 00000000000..019c257fe7d --- /dev/null +++ b/tests/baselines/reference/relationalOperatorComparable.js @@ -0,0 +1,34 @@ +//// [relationalOperatorComparable.ts] +function f(onethree: 1 | 3, two: 2) { + const t = true; + const f = false; + let a1 = onethree < two; // ok + let a2 = onethree < true; // error, number and boolean + let a3 = onethree <= false; // error, number and boolean + let a4 = onethree >= t; // error, number and boolean + let a5 = onethree > f; // error, number and boolean + let a6 = true < onethree; // error, boolean and number + let a7 = false < two; // error, boolean and number + let a8 = 'foo' < onethree; // error, string and number + let a9 = onethree < 1; // ok + let a10 = 1 < two; // ok + let a11 = 2 < 1; // ok +} + + +//// [relationalOperatorComparable.js] +function f(onethree, two) { + var t = true; + var f = false; + var a1 = onethree < two; // ok + var a2 = onethree < true; // error, number and boolean + var a3 = onethree <= false; // error, number and boolean + var a4 = onethree >= t; // error, number and boolean + var a5 = onethree > f; // error, number and boolean + var a6 = true < onethree; // error, boolean and number + var a7 = false < two; // error, boolean and number + var a8 = 'foo' < onethree; // error, string and number + var a9 = onethree < 1; // ok + var a10 = 1 < two; // ok + var a11 = 2 < 1; // ok +} diff --git a/tests/cases/compiler/relationalOperatorComparable.ts b/tests/cases/compiler/relationalOperatorComparable.ts new file mode 100644 index 00000000000..e95bb6e71cc --- /dev/null +++ b/tests/cases/compiler/relationalOperatorComparable.ts @@ -0,0 +1,15 @@ +function f(onethree: 1 | 3, two: 2) { + const t = true; + const f = false; + let a1 = onethree < two; // ok + let a2 = onethree < true; // error, number and boolean + let a3 = onethree <= false; // error, number and boolean + let a4 = onethree >= t; // error, number and boolean + let a5 = onethree > f; // error, number and boolean + let a6 = true < onethree; // error, boolean and number + let a7 = false < two; // error, boolean and number + let a8 = 'foo' < onethree; // error, string and number + let a9 = onethree < 1; // ok + let a10 = 1 < two; // ok + let a11 = 2 < 1; // ok +}