Skip to content

Commit

Permalink
Fixes #20026 (#20157)
Browse files Browse the repository at this point in the history
* Added test case for #20026

* Implemented #20026

* Addresed comments at /pull/20157#discussion_r152086287

* Fixed merge issues

* Fixed baseline issue

* Merged upstream
  • Loading branch information
remojansen authored and mhegazy committed Jan 9, 2018
1 parent c4d7629 commit 73e3e8d
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 11 deletions.
44 changes: 34 additions & 10 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15845,17 +15845,35 @@ namespace ts {
});
}

function checkNonNullExpression(node: Expression | QualifiedName) {
return checkNonNullType(checkExpression(node), node);
}

function checkNonNullType(type: Type, errorNode: Node): Type {
function checkNonNullExpression(
node: Expression | QualifiedName,
nullDiagnostic?: DiagnosticMessage,
undefinedDiagnostic?: DiagnosticMessage,
nullOrUndefinedDiagnostic?: DiagnosticMessage,
) {
return checkNonNullType(
checkExpression(node),
node,
nullDiagnostic,
undefinedDiagnostic,
nullOrUndefinedDiagnostic
);
}

function checkNonNullType(
type: Type,
node: Node,
nullDiagnostic?: DiagnosticMessage,
undefinedDiagnostic?: DiagnosticMessage,
nullOrUndefinedDiagnostic?: DiagnosticMessage
): Type {
const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable;
if (kind) {
error(errorNode, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ?
Diagnostics.Object_is_possibly_null_or_undefined :
Diagnostics.Object_is_possibly_undefined :
Diagnostics.Object_is_possibly_null);
error(node, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ?
(nullOrUndefinedDiagnostic || Diagnostics.Object_is_possibly_null_or_undefined) :
(undefinedDiagnostic || Diagnostics.Object_is_possibly_undefined) :
(nullDiagnostic || Diagnostics.Object_is_possibly_null)
);
const t = getNonNullableType(type);
return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? unknownType : t;
}
Expand Down Expand Up @@ -17364,7 +17382,13 @@ namespace ts {
return resolveUntypedCall(node);
}

const funcType = checkNonNullExpression(node.expression);
const funcType = checkNonNullExpression(
node.expression,
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null,
Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined,
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined
);

if (funcType === silentNeverType) {
return silentNeverSignature;
}
Expand Down
13 changes: 12 additions & 1 deletion src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2288,7 +2288,18 @@
"category": "Error",
"code": 2720
},

"Cannot invoke an object which is possibly 'null'.": {
"category": "Error",
"code": 2721
},
"Cannot invoke an object which is possibly 'undefined'.": {
"category": "Error",
"code": 2722
},
"Cannot invoke an object which is possibly 'null' or 'undefined'.": {
"category": "Error",
"code": 2723
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
"code": 4000
Expand Down
17 changes: 17 additions & 0 deletions tests/baselines/reference/nullableFunctionError.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
tests/cases/compiler/nullableFunctionError.ts(1,1): error TS2721: Cannot invoke an object which is possibly 'null'.
tests/cases/compiler/nullableFunctionError.ts(2,1): error TS2722: Cannot invoke an object which is possibly 'undefined'.
tests/cases/compiler/nullableFunctionError.ts(4,1): error TS2723: Cannot invoke an object which is possibly 'null' or 'undefined'.


==== tests/cases/compiler/nullableFunctionError.ts (3 errors) ====
null();
~~~~
!!! error TS2721: Cannot invoke an object which is possibly 'null'.
undefined();
~~~~~~~~~
!!! error TS2722: Cannot invoke an object which is possibly 'undefined'.
let f: null | undefined;
f();
~
!!! error TS2723: Cannot invoke an object which is possibly 'null' or 'undefined'.

12 changes: 12 additions & 0 deletions tests/baselines/reference/nullableFunctionError.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//// [nullableFunctionError.ts]
null();
undefined();
let f: null | undefined;
f();


//// [nullableFunctionError.js]
null();
undefined();
var f;
f();
11 changes: 11 additions & 0 deletions tests/baselines/reference/nullableFunctionError.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
=== tests/cases/compiler/nullableFunctionError.ts ===
null();
undefined();
>undefined : Symbol(undefined)

let f: null | undefined;
>f : Symbol(f, Decl(nullableFunctionError.ts, 2, 3))

f();
>f : Symbol(f, Decl(nullableFunctionError.ts, 2, 3))

17 changes: 17 additions & 0 deletions tests/baselines/reference/nullableFunctionError.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
=== tests/cases/compiler/nullableFunctionError.ts ===
null();
>null() : any
>null : null

undefined();
>undefined() : any
>undefined : undefined

let f: null | undefined;
>f : null | undefined
>null : null

f();
>f() : any
>f : null | undefined

6 changes: 6 additions & 0 deletions tests/cases/compiler/nullableFunctionError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// @strictNullChecks: true

null();
undefined();
let f: null | undefined;
f();

0 comments on commit 73e3e8d

Please sign in to comment.