Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 21 additions & 7 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26462,14 +26462,28 @@ namespace ts {
}
// For a binding pattern, validate the initializer and exit
if (isBindingPattern(node.name)) {
// Don't validate for-in initializer as it is already an error
if (node.initializer && node.parent.parent.kind !== SyntaxKind.ForInStatement) {
const initializerType = checkExpressionCached(node.initializer);
if (strictNullChecks && node.name.elements.length === 0) {
checkNonNullNonVoidType(initializerType, node);
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
const widenedType = getWidenedTypeForVariableLikeDeclaration(node);
if (needCheckInitializer) {
const initializerType = checkExpressionCached(node.initializer!);
if (strictNullChecks && needCheckWidenedType) {
checkNonNullNonVoidType(initializerType, node);
}
else {
checkTypeAssignableToAndOptionallyElaborate(initializerType, getWidenedTypeForVariableLikeDeclaration(node), node, node.initializer);
}
}
else {
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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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 changes: 32 additions & 0 deletions tests/baselines/reference/destructuringAssignabilityCheck.js
Original file line number Diff line number Diff line change
@@ -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 = {};
24 changes: 24 additions & 0 deletions tests/baselines/reference/destructuringAssignabilityCheck.symbols
Original file line number Diff line number Diff line change
@@ -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 []: {} = {}

40 changes: 40 additions & 0 deletions tests/baselines/reference/destructuringAssignabilityCheck.types
Original file line number Diff line number Diff line change
@@ -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 []: {} = {}
>{} : {}

Original file line number Diff line number Diff line change
@@ -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(5,5): error TS2531: Object is possibly 'null'.
tests/cases/compiler/strictNullEmptyDestructuring.ts(7,2): error TS2531: Object is possibly 'null'.
Expand All @@ -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 (11 errors) ====
==== tests/cases/compiler/strictNullEmptyDestructuring.ts (12 errors) ====
// Repro from #20873

let [] = null;
~~
!!! error TS2461: Type 'null' is not an array type.
~~
!!! error TS2531: Object is possibly 'null'.

let { } = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -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 []: {} = {}