Allow case comparison to undefined and null in strict null checking mode

This commit is contained in:
Nathan Shively-Sanders 2016-06-07 07:51:34 -07:00
parent 53a5b422b4
commit 843aa6c1ef
8 changed files with 98 additions and 1 deletions

View File

@ -15106,7 +15106,7 @@ namespace ts {
// In a 'switch' statement, each 'case' expression must be of a type that is comparable
// to or from the type of the 'switch' expression.
const caseType = checkExpression(caseClause.expression);
if (!isTypeComparableTo(expressionType, caseType)) {
if (!isTypeEqualityComparableTo(expressionType, caseType)) {
// expressionType is not comparable to caseType, try the reversed check and report errors if it fails
checkTypeComparableTo(caseType, expressionType, caseClause.expression, /*headMessage*/ undefined);
}

View File

@ -0,0 +1,18 @@
tests/cases/conformance/types/contextualTypes/methodDeclarations/contextuallyTypedObjectLiteralReturnType.ts(6,24): error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
tests/cases/conformance/types/contextualTypes/methodDeclarations/contextuallyTypedObjectLiteralReturnType.ts(7,38): error TS2339: Property 'length' does not exist on type 'number'.
==== tests/cases/conformance/types/contextualTypes/methodDeclarations/contextuallyTypedObjectLiteralReturnType.ts (2 errors) ====
function id<T>(x: T): T { return x };
// Correct: type of fnWrapper is (y: number) => { y: number }
var fn = function(y: number) { return { y } };
var fnWrapper = id(fn);
// Incorrect: type of inlineWrapper is (z: number) => any
var inlineWrapper = id(function(z: number) { return { z } });
~~~~~~~~
!!! error TS7024: Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
let error1: number = fnWrapper(12).y.length; // should error
~~~~~~
!!! error TS2339: Property 'length' does not exist on type 'number'.
let error2: number = inlineWrapper(12).z.length; // should error

View File

@ -0,0 +1,21 @@
//// [contextuallyTypedObjectLiteralReturnType.ts]
function id<T>(x: T): T { return x };
// Correct: type of fnWrapper is (y: number) => { y: number }
var fn = function(y: number) { return { y } };
var fnWrapper = id(fn);
// Incorrect: type of inlineWrapper is (z: number) => any
var inlineWrapper = id(function(z: number) { return { z } });
let error1: number = fnWrapper(12).y.length; // should error
let error2: number = inlineWrapper(12).z.length; // should error
//// [contextuallyTypedObjectLiteralReturnType.js]
function id(x) { return x; }
;
// Correct: type of fnWrapper is (y: number) => { y: number }
var fn = function (y) { return { y: y }; };
var fnWrapper = id(fn);
// Incorrect: type of inlineWrapper is (z: number) => any
var inlineWrapper = id(function (z) { return { z: z }; });
var error1 = fnWrapper(12).y.length; // should error
var error2 = inlineWrapper(12).z.length; // should error

View File

@ -81,4 +81,14 @@ tests/cases/conformance/types/typeRelationships/comparable/equalityStrictNulls.t
!!! error TS2365: Operator '<=' cannot be applied to types 'number' and 'undefined'.
}
}
function f5(x: string) {
switch(x) {
case null:
break;
case undefined:
break;
default:
return;
}
}

View File

@ -67,6 +67,16 @@ function f4(x: number) {
if (x <= undefined) {
}
}
function f5(x: string) {
switch(x) {
case null:
break;
case undefined:
break;
default:
return;
}
}
//// [equalityStrictNulls.js]
@ -134,3 +144,13 @@ function f4(x) {
if (x <= undefined) {
}
}
function f5(x) {
switch (x) {
case null:
break;
case undefined:
break;
default:
return;
}
}

View File

@ -0,0 +1,9 @@
interface Ctor<T> {
new(): T;
}
// declare function create1<T>(ctor: Ctor<T>): T;
declare function create2<T, C extends Ctor<T>>(ctor: C): T;
class A { a: number }
// let a1 = create1(A).a; // a: A --> OK
let a2 = create2(A).a; // a: {} --> Should be A

View File

@ -0,0 +1,9 @@
// @noImplicitAny: true
function id<T>(x: T): T { return x };
// Correct: type of fnWrapper is (y: number) => { y: number }
var fn = function(y: number) { return { y } };
var fnWrapper = id(fn);
// Incorrect: type of inlineWrapper is (z: number) => any
var inlineWrapper = id(function(z: number) { return { z } });
let error1: number = fnWrapper(12).y.length; // should error
let error2: number = inlineWrapper(12).z.length; // should error

View File

@ -67,3 +67,13 @@ function f4(x: number) {
if (x <= undefined) {
}
}
function f5(x: string) {
switch(x) {
case null:
break;
case undefined:
break;
default:
return;
}
}