fix false positive 'variable is used before being assigned' in destructuring (#29636)

Fixes: #29458
This commit is contained in:
Klaus Meinhardt
2019-04-23 22:22:37 +02:00
committed by Ryan Cavanaugh
parent 6487d1ffe0
commit 760393f893
6 changed files with 78 additions and 1 deletions

View File

@@ -17089,7 +17089,7 @@ namespace ts {
// We only look for uninitialized variables in strict null checking mode, and only when we can analyze
// the entire control flow graph from the variable's declaration (i.e. when the flow container and
// declaration container are the same).
const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports ||
const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isBindingElement(declaration) ||
type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.AnyOrUnknown) !== 0 ||
isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) ||
node.parent.kind === SyntaxKind.NonNullExpression ||

View File

@@ -0,0 +1,13 @@
tests/cases/compiler/useBeforeDeclaration_destructuring.ts(1,1): error TS2448: Block-scoped variable 'a' used before its declaration.
==== tests/cases/compiler/useBeforeDeclaration_destructuring.ts (1 errors) ====
a;
~
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
!!! related TS2728 tests/cases/compiler/useBeforeDeclaration_destructuring.ts:2:6: 'a' is declared here.
let {a, b = a} = {a: '', b: 1};
b;
function test({c, d = c}: Record<string, number>) {}

View File

@@ -0,0 +1,15 @@
//// [useBeforeDeclaration_destructuring.ts]
a;
let {a, b = a} = {a: '', b: 1};
b;
function test({c, d = c}: Record<string, number>) {}
//// [useBeforeDeclaration_destructuring.js]
a;
var _a = { a: '', b: 1 }, a = _a.a, _b = _a.b, b = _b === void 0 ? a : _b;
b;
function test(_a) {
var c = _a.c, _b = _a.d, d = _b === void 0 ? c : _b;
}

View File

@@ -0,0 +1,21 @@
=== tests/cases/compiler/useBeforeDeclaration_destructuring.ts ===
a;
>a : Symbol(a, Decl(useBeforeDeclaration_destructuring.ts, 1, 5))
let {a, b = a} = {a: '', b: 1};
>a : Symbol(a, Decl(useBeforeDeclaration_destructuring.ts, 1, 5))
>b : Symbol(b, Decl(useBeforeDeclaration_destructuring.ts, 1, 7))
>a : Symbol(a, Decl(useBeforeDeclaration_destructuring.ts, 1, 5))
>a : Symbol(a, Decl(useBeforeDeclaration_destructuring.ts, 1, 18))
>b : Symbol(b, Decl(useBeforeDeclaration_destructuring.ts, 1, 24))
b;
>b : Symbol(b, Decl(useBeforeDeclaration_destructuring.ts, 1, 7))
function test({c, d = c}: Record<string, number>) {}
>test : Symbol(test, Decl(useBeforeDeclaration_destructuring.ts, 2, 2))
>c : Symbol(c, Decl(useBeforeDeclaration_destructuring.ts, 4, 15))
>d : Symbol(d, Decl(useBeforeDeclaration_destructuring.ts, 4, 17))
>c : Symbol(c, Decl(useBeforeDeclaration_destructuring.ts, 4, 15))
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))

View File

@@ -0,0 +1,23 @@
=== tests/cases/compiler/useBeforeDeclaration_destructuring.ts ===
a;
>a : any
let {a, b = a} = {a: '', b: 1};
>a : any
>b : any
>a : any
>{a: '', b: 1} : { a: string; b?: number; }
>a : string
>'' : ""
>b : number
>1 : 1
b;
>b : any
function test({c, d = c}: Record<string, number>) {}
>test : ({ c, d }: Record<string, number>) => void
>c : number
>d : number
>c : number

View File

@@ -0,0 +1,5 @@
a;
let {a, b = a} = {a: '', b: 1};
b;
function test({c, d = c}: Record<string, number>) {}