Skip to content

Commit c68947e

Browse files
committed
Contextually type initializers of binding elements
Previously they were not contextually typed, which meant that lambdas got completely incorrect types, and that types that rely on contextual typing, like tuples and string literal types, did not work correctly.
1 parent 5e53ba0 commit c68947e

1 file changed

Lines changed: 22 additions & 6 deletions

File tree

src/compiler/checker.ts

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2604,7 +2604,7 @@ namespace ts {
26042604
return name.kind === SyntaxKind.ComputedPropertyName && !isStringOrNumericLiteral((<ComputedPropertyName>name).expression.kind);
26052605
}
26062606

2607-
// Return the inferred type for a binding element
2607+
/** Return the inferred type for a binding element */
26082608
function getTypeForBindingElement(declaration: BindingElement): Type {
26092609
const pattern = <BindingPattern>declaration.parent;
26102610
const parentType = getTypeForBindingElementParent(<VariableLikeDeclaration>pattern.parent);
@@ -2630,6 +2630,9 @@ namespace ts {
26302630
// computed properties with non-literal names are treated as 'any'
26312631
return anyType;
26322632
}
2633+
if (declaration.initializer) {
2634+
getContextualType(declaration.initializer);
2635+
}
26332636

26342637
// Use type of the specified property, or otherwise, for a numeric name, the type of the numeric index signature,
26352638
// or otherwise the type of the string index signature.
@@ -7825,11 +7828,14 @@ namespace ts {
78257828
return undefined;
78267829
}
78277830

7828-
// In a variable, parameter or property declaration with a type annotation, the contextual type of an initializer
7829-
// expression is the type of the variable, parameter or property. Otherwise, in a parameter declaration of a
7830-
// contextually typed function expression, the contextual type of an initializer expression is the contextual type
7831-
// of the parameter. Otherwise, in a variable or parameter declaration with a binding pattern name, the contextual
7832-
// type of an initializer expression is the type implied by the binding pattern.
7831+
// In a variable, parameter or property declaration with a type annotation,
7832+
// the contextual type of an initializer expression is the type of the variable, parameter or property.
7833+
// Otherwise, in a parameter declaration of a contextually typed function expression,
7834+
// the contextual type of an initializer expression is the contextual type of the parameter.
7835+
// Otherwise, in a variable or parameter declaration with a binding pattern name,
7836+
// the contextual type of an initializer expression is the type implied by the binding pattern.
7837+
// Otherwise, in a binding pattern inside a variable or parameter declaration,
7838+
// the contextual type of an initializer expression is the type annotation of the containing declaration, if present.
78337839
function getContextualTypeForInitializerExpression(node: Expression): Type {
78347840
const declaration = <VariableLikeDeclaration>node.parent;
78357841
if (node === declaration.initializer) {
@@ -7845,6 +7851,16 @@ namespace ts {
78457851
if (isBindingPattern(declaration.name)) {
78467852
return getTypeFromBindingPattern(<BindingPattern>declaration.name, /*includePatternInType*/ true);
78477853
}
7854+
if (isBindingPattern(declaration.parent)) {
7855+
const parentDeclaration = declaration.parent.parent;
7856+
const name = declaration.propertyName || declaration.name;
7857+
if (isVariableLike(parentDeclaration) &&
7858+
parentDeclaration.type &&
7859+
(name.kind === SyntaxKind.Identifier || name.kind == SyntaxKind.StringLiteral)) {
7860+
const text = (<Identifier | LiteralExpression>name).text;
7861+
return getTypeOfPropertyOfType(getTypeFromTypeNode(parentDeclaration.type), text);
7862+
}
7863+
}
78487864
}
78497865
return undefined;
78507866
}

0 commit comments

Comments
 (0)