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
This commit is contained in:
parent
d934401265
commit
454b4280b1
|
@ -26462,16 +26462,30 @@ namespace ts {
|
||||||
}
|
}
|
||||||
// For a binding pattern, validate the initializer and exit
|
// For a binding pattern, validate the initializer and exit
|
||||||
if (isBindingPattern(node.name)) {
|
if (isBindingPattern(node.name)) {
|
||||||
|
const needCheckInitializer = node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement;
|
||||||
|
const needCheckWidenedType = node.name.elements.length === 0;
|
||||||
|
if (needCheckInitializer || needCheckWidenedType) {
|
||||||
// Don't validate for-in initializer as it is already an error
|
// Don't validate for-in initializer as it is already an error
|
||||||
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
|
const widenedType = getWidenedTypeForVariableLikeDeclaration(node);
|
||||||
const initializerType = checkExpressionCached(node.initializer);
|
if (needCheckInitializer) {
|
||||||
if (strictNullChecks && node.name.elements.length === 0) {
|
const initializerType = checkExpressionCached(node.initializer!);
|
||||||
|
if (strictNullChecks && needCheckWidenedType) {
|
||||||
checkNonNullNonVoidType(initializerType, node);
|
checkNonNullNonVoidType(initializerType, node);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
|
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// check the binding pattern with empty elements
|
||||||
|
if (needCheckWidenedType) {
|
||||||
|
if (isArrayBindingPattern(node.name)) {
|
||||||
|
checkIteratedTypeOrElementType(widenedType, node, /* allowStringInput */ false, /* allowAsyncIterables */ false);
|
||||||
|
}
|
||||||
|
else if (strictNullChecks) {
|
||||||
|
checkNonNullNonVoidType(widenedType, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const symbol = getSymbolOfNode(node);
|
const symbol = getSymbolOfNode(node);
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(1,7): error TS2461: Type '{}' is not an array type.
|
||||||
|
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(2,7): error TS2532: Object is possibly 'undefined'.
|
||||||
|
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(3,3): error TS2461: Type '{}' is not an array type.
|
||||||
|
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(4,3): error TS2532: Object is possibly 'undefined'.
|
||||||
|
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(6,14): error TS2532: Object is possibly 'undefined'.
|
||||||
|
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(9,14): error TS2461: Type '{}' is not an array type.
|
||||||
|
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(13,7): error TS2532: Object is possibly 'undefined'.
|
||||||
|
tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts(15,7): error TS2461: Type '{}' is not an array type.
|
||||||
|
|
||||||
|
|
||||||
|
==== tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts (8 errors) ====
|
||||||
|
const [] = {}; // should be error
|
||||||
|
~~
|
||||||
|
!!! error TS2461: Type '{}' is not an array type.
|
||||||
|
const {} = undefined; // error correctly
|
||||||
|
~~
|
||||||
|
!!! error TS2532: Object is possibly 'undefined'.
|
||||||
|
(([]) => 0)({}); // should be error
|
||||||
|
~~
|
||||||
|
!!! error TS2461: Type '{}' is not an array type.
|
||||||
|
(({}) => 0)(undefined); // should be error
|
||||||
|
~~
|
||||||
|
!!! error TS2532: Object is possibly 'undefined'.
|
||||||
|
|
||||||
|
function foo({}: undefined) {
|
||||||
|
~~~~~~~~~~~~~
|
||||||
|
!!! error TS2532: Object is possibly 'undefined'.
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
function bar([]: {}) {
|
||||||
|
~~~~~~
|
||||||
|
!!! error TS2461: Type '{}' is not an array type.
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const { }: undefined = 1
|
||||||
|
~~~
|
||||||
|
!!! error TS2532: Object is possibly 'undefined'.
|
||||||
|
|
||||||
|
const []: {} = {}
|
||||||
|
~~
|
||||||
|
!!! error TS2461: Type '{}' is not an array type.
|
||||||
|
|
32
tests/baselines/reference/destructuringAssignabilityCheck.js
Normal file
32
tests/baselines/reference/destructuringAssignabilityCheck.js
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
//// [destructuringAssignabilityCheck.ts]
|
||||||
|
const [] = {}; // should be error
|
||||||
|
const {} = undefined; // error correctly
|
||||||
|
(([]) => 0)({}); // should be error
|
||||||
|
(({}) => 0)(undefined); // should be error
|
||||||
|
|
||||||
|
function foo({}: undefined) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
function bar([]: {}) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const { }: undefined = 1
|
||||||
|
|
||||||
|
const []: {} = {}
|
||||||
|
|
||||||
|
|
||||||
|
//// [destructuringAssignabilityCheck.js]
|
||||||
|
"use strict";
|
||||||
|
var _a = {}; // should be error
|
||||||
|
var _b = undefined; // error correctly
|
||||||
|
(function (_a) { return 0; })({}); // should be error
|
||||||
|
(function (_a) { return 0; })(undefined); // should be error
|
||||||
|
function foo(_a) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
function bar(_a) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var _c = 1;
|
||||||
|
var _d = {};
|
|
@ -0,0 +1,24 @@
|
||||||
|
=== tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts ===
|
||||||
|
const [] = {}; // should be error
|
||||||
|
const {} = undefined; // error correctly
|
||||||
|
>undefined : Symbol(undefined)
|
||||||
|
|
||||||
|
(([]) => 0)({}); // should be error
|
||||||
|
(({}) => 0)(undefined); // should be error
|
||||||
|
>undefined : Symbol(undefined)
|
||||||
|
|
||||||
|
function foo({}: undefined) {
|
||||||
|
>foo : Symbol(foo, Decl(destructuringAssignabilityCheck.ts, 3, 23))
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
function bar([]: {}) {
|
||||||
|
>bar : Symbol(bar, Decl(destructuringAssignabilityCheck.ts, 7, 1))
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const { }: undefined = 1
|
||||||
|
|
||||||
|
const []: {} = {}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
=== tests/cases/conformance/es6/destructuring/destructuringAssignabilityCheck.ts ===
|
||||||
|
const [] = {}; // should be error
|
||||||
|
>{} : {}
|
||||||
|
|
||||||
|
const {} = undefined; // error correctly
|
||||||
|
>undefined : undefined
|
||||||
|
|
||||||
|
(([]) => 0)({}); // should be error
|
||||||
|
>(([]) => 0)({}) : number
|
||||||
|
>(([]) => 0) : ([]: {}) => number
|
||||||
|
>([]) => 0 : ([]: {}) => number
|
||||||
|
>0 : 0
|
||||||
|
>{} : {}
|
||||||
|
|
||||||
|
(({}) => 0)(undefined); // should be error
|
||||||
|
>(({}) => 0)(undefined) : number
|
||||||
|
>(({}) => 0) : ({}: undefined) => number
|
||||||
|
>({}) => 0 : ({}: undefined) => number
|
||||||
|
>0 : 0
|
||||||
|
>undefined : undefined
|
||||||
|
|
||||||
|
function foo({}: undefined) {
|
||||||
|
>foo : ({}: undefined) => number
|
||||||
|
|
||||||
|
return 0
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
function bar([]: {}) {
|
||||||
|
>bar : ([]: {}) => number
|
||||||
|
|
||||||
|
return 0
|
||||||
|
>0 : 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const { }: undefined = 1
|
||||||
|
>1 : 1
|
||||||
|
|
||||||
|
const []: {} = {}
|
||||||
|
>{} : {}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
tests/cases/compiler/strictNullEmptyDestructuring.ts(3,5): error TS2461: Type 'null' is not an array type.
|
||||||
tests/cases/compiler/strictNullEmptyDestructuring.ts(3,5): error TS2531: Object is possibly 'null'.
|
tests/cases/compiler/strictNullEmptyDestructuring.ts(3,5): error TS2531: Object is possibly 'null'.
|
||||||
tests/cases/compiler/strictNullEmptyDestructuring.ts(5,5): error TS2531: Object is possibly 'null'.
|
tests/cases/compiler/strictNullEmptyDestructuring.ts(5,5): error TS2531: Object is possibly 'null'.
|
||||||
tests/cases/compiler/strictNullEmptyDestructuring.ts(7,2): error TS2531: Object is possibly 'null'.
|
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
|
||||||
tests/cases/compiler/strictNullEmptyDestructuring.ts(23,2): error TS2533: Object is possibly 'null' or 'undefined'.
|
tests/cases/compiler/strictNullEmptyDestructuring.ts(23,2): error TS2533: Object is possibly 'null' or 'undefined'.
|
||||||
|
|
||||||
|
|
||||||
==== tests/cases/compiler/strictNullEmptyDestructuring.ts (11 errors) ====
|
==== tests/cases/compiler/strictNullEmptyDestructuring.ts (12 errors) ====
|
||||||
// Repro from #20873
|
// Repro from #20873
|
||||||
|
|
||||||
let [] = null;
|
let [] = null;
|
||||||
~~
|
~~
|
||||||
|
!!! error TS2461: Type 'null' is not an array type.
|
||||||
|
~~
|
||||||
!!! error TS2531: Object is possibly 'null'.
|
!!! error TS2531: Object is possibly 'null'.
|
||||||
|
|
||||||
let { } = null;
|
let { } = null;
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
// @strict: true
|
||||||
|
|
||||||
|
const [] = {}; // should be error
|
||||||
|
const {} = undefined; // error correctly
|
||||||
|
(([]) => 0)({}); // should be error
|
||||||
|
(({}) => 0)(undefined); // should be error
|
||||||
|
|
||||||
|
function foo({}: undefined) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
function bar([]: {}) {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
const { }: undefined = 1
|
||||||
|
|
||||||
|
const []: {} = {}
|
Loading…
Reference in a new issue