Skip to content

Commit

Permalink
Merge pull request #8452 from Microsoft/equalityUndefinedAndNull
Browse files Browse the repository at this point in the history
Allow equality comparisons to undefined and null in strict null checking mode
  • Loading branch information
ahejlsberg committed May 4, 2016
2 parents 7f82beb + e828fce commit cb9be66
Show file tree
Hide file tree
Showing 4 changed files with 299 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12053,6 +12053,10 @@ namespace ts {
return sourceType;
}

function isTypeEqualityComparableTo(source: Type, target: Type) {
return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target);
}

function checkBinaryExpression(node: BinaryExpression, contextualMapper?: TypeMapper) {
return checkBinaryLikeExpression(node.left, node.operatorToken, node.right, contextualMapper, node);
}
Expand Down Expand Up @@ -12166,15 +12170,17 @@ namespace ts {
case SyntaxKind.GreaterThanToken:
case SyntaxKind.LessThanEqualsToken:
case SyntaxKind.GreaterThanEqualsToken:
if (!checkForDisallowedESSymbolOperand(operator)) {
return booleanType;
if (checkForDisallowedESSymbolOperand(operator)) {
if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) {
reportOperatorError();
}
}
// Fall through
return booleanType;
case SyntaxKind.EqualsEqualsToken:
case SyntaxKind.ExclamationEqualsToken:
case SyntaxKind.EqualsEqualsEqualsToken:
case SyntaxKind.ExclamationEqualsEqualsToken:
if (!isTypeComparableTo(leftType, rightType) && !isTypeComparableTo(rightType, leftType)) {
if (!isTypeEqualityComparableTo(leftType, rightType) && !isTypeEqualityComparableTo(rightType, leftType)) {
reportOperatorError();
}
return booleanType;
Expand Down
84 changes: 84 additions & 0 deletions tests/baselines/reference/equalityStrictNulls.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(60,9): error TS2365: Operator '>' cannot be applied to types 'number' and 'undefined'.
tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(62,9): error TS2365: Operator '<' cannot be applied to types 'number' and 'undefined'.
tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(64,9): error TS2365: Operator '>=' cannot be applied to types 'number' and 'undefined'.
tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts(66,9): error TS2365: Operator '<=' cannot be applied to types 'number' and 'undefined'.


==== tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.ts (4 errors) ====

function f1(x: string) {
if (x == undefined) {
}
if (x != undefined) {
}
if (x === undefined) {
}
if (x !== undefined) {
}
if (x == null) {
}
if (x != null) {
}
if (x === null) {
}
if (x !== null) {
}
if (undefined == x) {
}
if (undefined != x) {
}
if (undefined === x) {
}
if (undefined !== x) {
}
if (null == x) {
}
if (null != x) {
}
if (null === x) {
}
if (null !== x) {
}
}

function f2() {
if (undefined == undefined) {
}
if (undefined == null) {
}
if (null == undefined) {
}
if (null == null) {
}
}

function f3(a: number, b: boolean, c: { x: number }, d: number | string) {
if (a == null) {
}
if (b == null) {
}
if (c == null) {
}
if (d == null) {
}
}

function f4(x: number) {
if (x > undefined) {
~~~~~~~~~~~~~
!!! error TS2365: Operator '>' cannot be applied to types 'number' and 'undefined'.
}
if (x < undefined) {
~~~~~~~~~~~~~
!!! error TS2365: Operator '<' cannot be applied to types 'number' and 'undefined'.
}
if (x >= undefined) {
~~~~~~~~~~~~~~
!!! error TS2365: Operator '>=' cannot be applied to types 'number' and 'undefined'.
}
if (x <= undefined) {
~~~~~~~~~~~~~~
!!! error TS2365: Operator '<=' cannot be applied to types 'number' and 'undefined'.
}
}

136 changes: 136 additions & 0 deletions tests/baselines/reference/equalityStrictNulls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
//// [equalityStrictNulls.ts]

function f1(x: string) {
if (x == undefined) {
}
if (x != undefined) {
}
if (x === undefined) {
}
if (x !== undefined) {
}
if (x == null) {
}
if (x != null) {
}
if (x === null) {
}
if (x !== null) {
}
if (undefined == x) {
}
if (undefined != x) {
}
if (undefined === x) {
}
if (undefined !== x) {
}
if (null == x) {
}
if (null != x) {
}
if (null === x) {
}
if (null !== x) {
}
}

function f2() {
if (undefined == undefined) {
}
if (undefined == null) {
}
if (null == undefined) {
}
if (null == null) {
}
}

function f3(a: number, b: boolean, c: { x: number }, d: number | string) {
if (a == null) {
}
if (b == null) {
}
if (c == null) {
}
if (d == null) {
}
}

function f4(x: number) {
if (x > undefined) {
}
if (x < undefined) {
}
if (x >= undefined) {
}
if (x <= undefined) {
}
}


//// [equalityStrictNulls.js]
function f1(x) {
if (x == undefined) {
}
if (x != undefined) {
}
if (x === undefined) {
}
if (x !== undefined) {
}
if (x == null) {
}
if (x != null) {
}
if (x === null) {
}
if (x !== null) {
}
if (undefined == x) {
}
if (undefined != x) {
}
if (undefined === x) {
}
if (undefined !== x) {
}
if (null == x) {
}
if (null != x) {
}
if (null === x) {
}
if (null !== x) {
}
}
function f2() {
if (undefined == undefined) {
}
if (undefined == null) {
}
if (null == undefined) {
}
if (null == null) {
}
}
function f3(a, b, c, d) {
if (a == null) {
}
if (b == null) {
}
if (c == null) {
}
if (d == null) {
}
}
function f4(x) {
if (x > undefined) {
}
if (x < undefined) {
}
if (x >= undefined) {
}
if (x <= undefined) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// @strictNullChecks: true

function f1(x: string) {
if (x == undefined) {
}
if (x != undefined) {
}
if (x === undefined) {
}
if (x !== undefined) {
}
if (x == null) {
}
if (x != null) {
}
if (x === null) {
}
if (x !== null) {
}
if (undefined == x) {
}
if (undefined != x) {
}
if (undefined === x) {
}
if (undefined !== x) {
}
if (null == x) {
}
if (null != x) {
}
if (null === x) {
}
if (null !== x) {
}
}

function f2() {
if (undefined == undefined) {
}
if (undefined == null) {
}
if (null == undefined) {
}
if (null == null) {
}
}

function f3(a: number, b: boolean, c: { x: number }, d: number | string) {
if (a == null) {
}
if (b == null) {
}
if (c == null) {
}
if (d == null) {
}
}

function f4(x: number) {
if (x > undefined) {
}
if (x < undefined) {
}
if (x >= undefined) {
}
if (x <= undefined) {
}
}

0 comments on commit cb9be66

Please sign in to comment.