Skip to content

Commit 454b428

Browse files
KingwlRyanCavanaugh
authored andcommitted
check more case for empty binding patten (#25263)
* check more case for empty binding patten * refactor binding pattern checking getWidenedType * fix spelling * fix merge and rebase
1 parent d934401 commit 454b428

7 files changed

+181
-8
lines changed

src/compiler/checker.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26462,14 +26462,28 @@ namespace ts {
2646226462
}
2646326463
// For a binding pattern, validate the initializer and exit
2646426464
if (isBindingPattern(node.name)) {
26465-
// Don't validate for-in initializer as it is already an error
26466-
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
26467-
const initializerType = checkExpressionCached(node.initializer);
26468-
if (strictNullChecks && node.name.elements.length === 0) {
26469-
checkNonNullNonVoidType(initializerType, node);
26465+
const needCheckInitializer = node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement;
26466+
const needCheckWidenedType = node.name.elements.length === 0;
26467+
if (needCheckInitializer || needCheckWidenedType) {
26468+
// Don't validate for-in initializer as it is already an error
26469+
const widenedType = getWidenedTypeForVariableLikeDeclaration(node);
26470+
if (needCheckInitializer) {
26471+
const initializerType = checkExpressionCached(node.initializer!);
26472+
if (strictNullChecks && needCheckWidenedType) {
26473+
checkNonNullNonVoidType(initializerType, node);
26474+
}
26475+
else {
26476+
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
26477+
}
2647026478
}
26471-
else {
26472-
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
26479+
// check the binding pattern with empty elements
26480+
if (needCheckWidenedType) {
26481+
if (isArrayBindingPattern(node.name)) {
26482+
checkIteratedTypeOrElementType(widenedType, node, /* allowStringInput */ false, /* allowAsyncIterables */ false);
26483+
}
26484+
else if (strictNullChecks) {
26485+
checkNonNullNonVoidType(widenedType, node);
26486+
}
2647326487
}
2647426488
}
2647526489
return;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(1,7): error TS2461: Type '{}' is not an array type.
2+
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(2,7): error TS2532: Object is possibly 'undefined'.
3+
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(3,3): error TS2461: Type '{}' is not an array type.
4+
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(4,3): error TS2532: Object is possibly 'undefined'.
5+
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(6,14): error TS2532: Object is possibly 'undefined'.
6+
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(9,14): error TS2461: Type '{}' is not an array type.
7+
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(13,7): error TS2532: Object is possibly 'undefined'.
8+
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(15,7): error TS2461: Type '{}' is not an array type.
9+
10+
11+
==== tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts (8 errors) ====
12+
const [] = {}; // should be error
13+
~~
14+
!!! error TS2461: Type '{}' is not an array type.
15+
const {} = undefined; // error correctly
16+
~~
17+
!!! error TS2532: Object is possibly 'undefined'.
18+
(([]) => 0)({}); // should be error
19+
~~
20+
!!! error TS2461: Type '{}' is not an array type.
21+
(({}) => 0)(undefined); // should be error
22+
~~
23+
!!! error TS2532: Object is possibly 'undefined'.
24+
25+
function foo({}: undefined) {
26+
~~~~~~~~~~~~~
27+
!!! error TS2532: Object is possibly 'undefined'.
28+
return 0
29+
}
30+
function bar([]: {}) {
31+
~~~~~~
32+
!!! error TS2461: Type '{}' is not an array type.
33+
return 0
34+
}
35+
36+
const { }: undefined = 1
37+
~~~
38+
!!! error TS2532: Object is possibly 'undefined'.
39+
40+
const []: {} = {}
41+
~~
42+
!!! error TS2461: Type '{}' is not an array type.
43+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
//// [destructuringAssignabilityCheck.ts]
2+
const [] = {}; // should be error
3+
const {} = undefined; // error correctly
4+
(([]) => 0)({}); // should be error
5+
(({}) => 0)(undefined); // should be error
6+
7+
function foo({}: undefined) {
8+
return 0
9+
}
10+
function bar([]: {}) {
11+
return 0
12+
}
13+
14+
const { }: undefined = 1
15+
16+
const []: {} = {}
17+
18+
19+
//// [destructuringAssignabilityCheck.js]
20+
"use strict";
21+
var _a = {}; // should be error
22+
var _b = undefined; // error correctly
23+
(function (_a) { return 0; })({}); // should be error
24+
(function (_a) { return 0; })(undefined); // should be error
25+
function foo(_a) {
26+
return 0;
27+
}
28+
function bar(_a) {
29+
return 0;
30+
}
31+
var _c = 1;
32+
var _d = {};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
=== tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts ===
2+
const [] = {}; // should be error
3+
const {} = undefined; // error correctly
4+
>undefined : Symbol(undefined)
5+
6+
(([]) => 0)({}); // should be error
7+
(({}) => 0)(undefined); // should be error
8+
>undefined : Symbol(undefined)
9+
10+
function foo({}: undefined) {
11+
>foo : Symbol(foo, Decl(destructuringAssignabilityCheck.ts, 3, 23))
12+
13+
return 0
14+
}
15+
function bar([]: {}) {
16+
>bar : Symbol(bar, Decl(destructuringAssignabilityCheck.ts, 7, 1))
17+
18+
return 0
19+
}
20+
21+
const { }: undefined = 1
22+
23+
const []: {} = {}
24+
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
=== tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts ===
2+
const [] = {}; // should be error
3+
>{} : {}
4+
5+
const {} = undefined; // error correctly
6+
>undefined : undefined
7+
8+
(([]) => 0)({}); // should be error
9+
>(([]) => 0)({}) : number
10+
>(([]) => 0) : ([]: {}) => number
11+
>([]) => 0 : ([]: {}) => number
12+
>0 : 0
13+
>{} : {}
14+
15+
(({}) => 0)(undefined); // should be error
16+
>(({}) => 0)(undefined) : number
17+
>(({}) => 0) : ({}: undefined) => number
18+
>({}) => 0 : ({}: undefined) => number
19+
>0 : 0
20+
>undefined : undefined
21+
22+
function foo({}: undefined) {
23+
>foo : ({}: undefined) => number
24+
25+
return 0
26+
>0 : 0
27+
}
28+
function bar([]: {}) {
29+
>bar : ([]: {}) => number
30+
31+
return 0
32+
>0 : 0
33+
}
34+
35+
const { }: undefined = 1
36+
>1 : 1
37+
38+
const []: {} = {}
39+
>{} : {}
40+

tests/baselines/reference/strictNullEmptyDestructuring.errors.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
tests/cases/compiler/strictNullEmptyDestructuring.ts(3,5): error TS2461: Type 'null' is not an array type.
12
tests/cases/compiler/strictNullEmptyDestructuring.ts(3,5): error TS2531: Object is possibly 'null'.
23
tests/cases/compiler/strictNullEmptyDestructuring.ts(5,5): error TS2531: Object is possibly 'null'.
34
tests/cases/compiler/strictNullEmptyDestructuring.ts(7,2): error TS2531: Object is possibly 'null'.
@@ -11,11 +12,13 @@ tests/cases/compiler/strictNullEmptyDestructuring.ts(21,5): error TS2533: Object
1112
tests/cases/compiler/strictNullEmptyDestructuring.ts(23,2): error TS2533: Object is possibly 'null' or 'undefined'.
1213

1314

14-
==== tests/cases/compiler/strictNullEmptyDestructuring.ts (11 errors) ====
15+
==== tests/cases/compiler/strictNullEmptyDestructuring.ts (12 errors) ====
1516
// Repro from #20873
1617

1718
let [] = null;
1819
~~
20+
!!! error TS2461: Type 'null' is not an array type.
21+
~~
1922
!!! error TS2531: Object is possibly 'null'.
2023

2124
let { } = null;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// @strict: true
2+
3+
const [] = {}; // should be error
4+
const {} = undefined; // error correctly
5+
(([]) => 0)({}); // should be error
6+
(({}) => 0)(undefined); // should be error
7+
8+
function foo({}: undefined) {
9+
return 0
10+
}
11+
function bar([]: {}) {
12+
return 0
13+
}
14+
15+
const { }: undefined = 1
16+
17+
const []: {} = {}

0 commit comments

Comments
 (0)