@@ -3322,7 +3322,7 @@ namespace ts {
33223322 type;
33233323 }
33243324
3325- function getTypeForVariableLikeDeclarationFromJSDocComment (declaration: VariableLikeDeclaration ) {
3325+ function getTypeForDeclarationFromJSDocComment (declaration: Node ) {
33263326 const jsdocType = getJSDocType(declaration);
33273327 if (jsdocType) {
33283328 return getTypeFromTypeNode(jsdocType);
@@ -3350,7 +3350,7 @@ namespace ts {
33503350 // If this is a variable in a JavaScript file, then use the JSDoc type (if it has
33513351 // one as its type), otherwise fallback to the below standard TS codepaths to
33523352 // try to figure it out.
3353- const type = getTypeForVariableLikeDeclarationFromJSDocComment (declaration);
3353+ const type = getTypeForDeclarationFromJSDocComment (declaration);
33543354 if (type && type !== unknownType) {
33553355 return type;
33563356 }
@@ -3445,6 +3445,27 @@ namespace ts {
34453445 return undefined;
34463446 }
34473447
3448+ // Return the inferred type for a variable, parameter, or property declaration
3449+ function getTypeForJSSpecialPropertyDeclaration(declaration: Declaration): Type {
3450+ const expression = declaration.kind === SyntaxKind.BinaryExpression ? <BinaryExpression>declaration :
3451+ declaration.kind === SyntaxKind.PropertyAccessExpression ? <BinaryExpression>getAncestor(declaration, SyntaxKind.BinaryExpression) :
3452+ undefined;
3453+
3454+ if (!expression) {
3455+ return unknownType;
3456+ }
3457+
3458+ if (expression.flags & NodeFlags.JavaScriptFile) {
3459+ // If there is a JSDoc type, use it
3460+ const type = getTypeForDeclarationFromJSDocComment(expression.parent);
3461+ if (type && type !== unknownType) {
3462+ return getWidenedType(type);
3463+ }
3464+ }
3465+
3466+ return getWidenedLiteralType(checkExpressionCached(expression.right));
3467+ }
3468+
34483469 // Return the type implied by a binding pattern element. This is the type of the initializer of the element if
34493470 // one is present. Otherwise, if the element is itself a binding pattern, it is the type implied by the binding
34503471 // pattern. Otherwise, it is the type any.
@@ -3599,18 +3620,7 @@ namespace ts {
35993620 // * className.prototype.method = expr
36003621 if (declaration.kind === SyntaxKind.BinaryExpression ||
36013622 declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) {
3602- // Use JS Doc type if present on parent expression statement
3603- if (declaration.flags & NodeFlags.JavaScriptFile) {
3604- const jsdocType = getJSDocType(declaration.parent);
3605- if (jsdocType) {
3606- return links.type = getTypeFromTypeNode(jsdocType);
3607- }
3608- }
3609- const declaredTypes = map(symbol.declarations,
3610- decl => decl.kind === SyntaxKind.BinaryExpression ?
3611- checkExpressionCached((<BinaryExpression>decl).right) :
3612- checkExpressionCached((<BinaryExpression>decl.parent).right));
3613- type = getUnionType(declaredTypes, /*subtypeReduction*/ true);
3623+ type = getWidenedType(getUnionType(map(symbol.declarations, getTypeForJSSpecialPropertyDeclaration), /*subtypeReduction*/ true));
36143624 }
36153625 else {
36163626 type = getWidenedTypeForVariableLikeDeclaration(<VariableLikeDeclaration>declaration, /*reportErrors*/ true);
@@ -3653,7 +3663,7 @@ namespace ts {
36533663 const setter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.SetAccessor);
36543664
36553665 if (getter && getter.flags & NodeFlags.JavaScriptFile) {
3656- const jsDocType = getTypeForVariableLikeDeclarationFromJSDocComment (getter);
3666+ const jsDocType = getTypeForDeclarationFromJSDocComment (getter);
36573667 if (jsDocType) {
36583668 return links.type = jsDocType;
36593669 }
@@ -9535,11 +9545,19 @@ namespace ts {
95359545 }
95369546
95379547 function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type {
9538- return node.parent.kind === SyntaxKind.ArrayLiteralExpression || node.parent.kind === SyntaxKind.PropertyAssignment ?
9548+ const isDestructuringDefaultAssignment =
9549+ node.parent.kind === SyntaxKind.ArrayLiteralExpression && isDestructuringAssignmentTarget(node.parent) ||
9550+ node.parent.kind === SyntaxKind.PropertyAssignment && isDestructuringAssignmentTarget(node.parent.parent);
9551+ return isDestructuringDefaultAssignment ?
95399552 getTypeWithDefault(getAssignedType(node), node.right) :
95409553 getTypeOfExpression(node.right);
95419554 }
95429555
9556+ function isDestructuringAssignmentTarget(parent: Node) {
9557+ return parent.parent.kind === SyntaxKind.BinaryExpression && (parent.parent as BinaryExpression).left === parent ||
9558+ parent.parent.kind === SyntaxKind.ForOfStatement && (parent.parent as ForOfStatement).initializer === parent;
9559+ }
9560+
95439561 function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type {
95449562 return getTypeOfDestructuredArrayElement(getAssignedType(node), indexOf(node.elements, element));
95459563 }
0 commit comments