Skip to content

Commit 73e3e8d

Browse files
remojansenmhegazy
authored andcommitted
Fixes #20026 (#20157)
* Added test case for #20026 * Implemented #20026 * Addresed comments at /pull/20157#discussion_r152086287 * Fixed merge issues * Fixed baseline issue * Merged upstream
1 parent c4d7629 commit 73e3e8d

File tree

7 files changed

+109
-11
lines changed

7 files changed

+109
-11
lines changed

src/compiler/checker.ts

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15845,17 +15845,35 @@ namespace ts {
1584515845
});
1584615846
}
1584715847

15848-
function checkNonNullExpression(node: Expression | QualifiedName) {
15849-
return checkNonNullType(checkExpression(node), node);
15850-
}
15851-
15852-
function checkNonNullType(type: Type, errorNode: Node): Type {
15848+
function checkNonNullExpression(
15849+
node: Expression | QualifiedName,
15850+
nullDiagnostic?: DiagnosticMessage,
15851+
undefinedDiagnostic?: DiagnosticMessage,
15852+
nullOrUndefinedDiagnostic?: DiagnosticMessage,
15853+
) {
15854+
return checkNonNullType(
15855+
checkExpression(node),
15856+
node,
15857+
nullDiagnostic,
15858+
undefinedDiagnostic,
15859+
nullOrUndefinedDiagnostic
15860+
);
15861+
}
15862+
15863+
function checkNonNullType(
15864+
type: Type,
15865+
node: Node,
15866+
nullDiagnostic?: DiagnosticMessage,
15867+
undefinedDiagnostic?: DiagnosticMessage,
15868+
nullOrUndefinedDiagnostic?: DiagnosticMessage
15869+
): Type {
1585315870
const kind = (strictNullChecks ? getFalsyFlags(type) : type.flags) & TypeFlags.Nullable;
1585415871
if (kind) {
15855-
error(errorNode, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ?
15856-
Diagnostics.Object_is_possibly_null_or_undefined :
15857-
Diagnostics.Object_is_possibly_undefined :
15858-
Diagnostics.Object_is_possibly_null);
15872+
error(node, kind & TypeFlags.Undefined ? kind & TypeFlags.Null ?
15873+
(nullOrUndefinedDiagnostic || Diagnostics.Object_is_possibly_null_or_undefined) :
15874+
(undefinedDiagnostic || Diagnostics.Object_is_possibly_undefined) :
15875+
(nullDiagnostic || Diagnostics.Object_is_possibly_null)
15876+
);
1585915877
const t = getNonNullableType(type);
1586015878
return t.flags & (TypeFlags.Nullable | TypeFlags.Never) ? unknownType : t;
1586115879
}
@@ -17364,7 +17382,13 @@ namespace ts {
1736417382
return resolveUntypedCall(node);
1736517383
}
1736617384

17367-
const funcType = checkNonNullExpression(node.expression);
17385+
const funcType = checkNonNullExpression(
17386+
node.expression,
17387+
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null,
17388+
Diagnostics.Cannot_invoke_an_object_which_is_possibly_undefined,
17389+
Diagnostics.Cannot_invoke_an_object_which_is_possibly_null_or_undefined
17390+
);
17391+
1736817392
if (funcType === silentNeverType) {
1736917393
return silentNeverSignature;
1737017394
}

src/compiler/diagnosticMessages.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2288,7 +2288,18 @@
22882288
"category": "Error",
22892289
"code": 2720
22902290
},
2291-
2291+
"Cannot invoke an object which is possibly 'null'.": {
2292+
"category": "Error",
2293+
"code": 2721
2294+
},
2295+
"Cannot invoke an object which is possibly 'undefined'.": {
2296+
"category": "Error",
2297+
"code": 2722
2298+
},
2299+
"Cannot invoke an object which is possibly 'null' or 'undefined'.": {
2300+
"category": "Error",
2301+
"code": 2723
2302+
},
22922303
"Import declaration '{0}' is using private name '{1}'.": {
22932304
"category": "Error",
22942305
"code": 4000
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
tests/cases/compiler/nullableFunctionError.ts(1,1): error TS2721: Cannot invoke an object which is possibly 'null'.
2+
tests/cases/compiler/nullableFunctionError.ts(2,1): error TS2722: Cannot invoke an object which is possibly 'undefined'.
3+
tests/cases/compiler/nullableFunctionError.ts(4,1): error TS2723: Cannot invoke an object which is possibly 'null' or 'undefined'.
4+
5+
6+
==== tests/cases/compiler/nullableFunctionError.ts (3 errors) ====
7+
null();
8+
~~~~
9+
!!! error TS2721: Cannot invoke an object which is possibly 'null'.
10+
undefined();
11+
~~~~~~~~~
12+
!!! error TS2722: Cannot invoke an object which is possibly 'undefined'.
13+
let f: null | undefined;
14+
f();
15+
~
16+
!!! error TS2723: Cannot invoke an object which is possibly 'null' or 'undefined'.
17+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//// [nullableFunctionError.ts]
2+
null();
3+
undefined();
4+
let f: null | undefined;
5+
f();
6+
7+
8+
//// [nullableFunctionError.js]
9+
null();
10+
undefined();
11+
var f;
12+
f();
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
=== tests/cases/compiler/nullableFunctionError.ts ===
2+
null();
3+
undefined();
4+
>undefined : Symbol(undefined)
5+
6+
let f: null | undefined;
7+
>f : Symbol(f, Decl(nullableFunctionError.ts, 2, 3))
8+
9+
f();
10+
>f : Symbol(f, Decl(nullableFunctionError.ts, 2, 3))
11+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/compiler/nullableFunctionError.ts ===
2+
null();
3+
>null() : any
4+
>null : null
5+
6+
undefined();
7+
>undefined() : any
8+
>undefined : undefined
9+
10+
let f: null | undefined;
11+
>f : null | undefined
12+
>null : null
13+
14+
f();
15+
>f() : any
16+
>f : null | undefined
17+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// @strictNullChecks: true
2+
3+
null();
4+
undefined();
5+
let f: null | undefined;
6+
f();

0 commit comments

Comments
 (0)