@@ -638,11 +638,24 @@ namespace ts {
638
638
639
639
if (declaration.pos <= usage.pos) {
640
640
// declaration is before usage
641
- // still might be illegal if usage is in the initializer of the variable declaration
642
- return declaration.kind !== SyntaxKind.VariableDeclaration ||
643
- !isImmediatelyUsedInInitializerOfBlockScopedVariable(<VariableDeclaration>declaration, usage);
641
+ if (declaration.kind === SyntaxKind.BindingElement) {
642
+ // still might be illegal if declaration and usage are both binding elements (eg var [a = b, b = b] = [1, 2])
643
+ const errorBindingElement = getAncestor(usage, SyntaxKind.BindingElement) as BindingElement;
644
+ if (errorBindingElement) {
645
+ return getAncestorBindingPattern(errorBindingElement) !== getAncestorBindingPattern(declaration) ||
646
+ declaration.pos < errorBindingElement.pos;
647
+ }
648
+ // or it might be illegal if usage happens before parent variable is declared (eg var [a] = a)
649
+ return isBlockScopedNameDeclaredBeforeUse(getAncestor(declaration, SyntaxKind.VariableDeclaration) as Declaration, usage);
650
+ }
651
+ else if (declaration.kind === SyntaxKind.VariableDeclaration) {
652
+ // still might be illegal if usage is in the initializer of the variable declaration (eg var a = a)
653
+ return !isImmediatelyUsedInInitializerOfBlockScopedVariable(declaration as VariableDeclaration, usage);
654
+ }
655
+ return true;
644
656
}
645
657
658
+
646
659
// declaration is after usage
647
660
// can be legal if usage is deferred (i.e. inside function or in initializer of instance property)
648
661
const container = getEnclosingBlockScopeContainer(declaration);
@@ -699,6 +712,16 @@ namespace ts {
699
712
}
700
713
return false;
701
714
}
715
+
716
+ function getAncestorBindingPattern(node: Node): BindingPattern {
717
+ while (node) {
718
+ if (isBindingPattern(node)) {
719
+ return node;
720
+ }
721
+ node = node.parent;
722
+ }
723
+ return undefined;
724
+ }
702
725
}
703
726
704
727
// Resolve a given name for a given meaning at a given location. An error is reported if the name was not found and
@@ -1065,7 +1088,7 @@ namespace ts {
1065
1088
1066
1089
Debug.assert(declaration !== undefined, "Block-scoped variable declaration is undefined");
1067
1090
1068
- if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(<Declaration>getAncestor( declaration, SyntaxKind.VariableDeclaration) , errorLocation)) {
1091
+ if (!isInAmbientContext(declaration) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
1069
1092
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(declaration.name));
1070
1093
}
1071
1094
}
0 commit comments