Merge pull request #8452 from Microsoft/equalityUndefinedAndNull

Allow equality comparisons to undefined and null in strict null checking mode
This commit is contained in:
Anders Hejlsberg 2016-05-03 17:52:14 -07:00
commit cb9be669ec
4 changed files with 299 additions and 4 deletions

View File

@ -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);
}
@ -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;

View File

@ -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'.
}
}

View File

@ -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) {
}
}

View File

@ -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) {
}
}