Merge pull request #4956 from Microsoft/bindingElementContextualTyping

Fix parameter destructuring issues
This commit is contained in:
Anders Hejlsberg
2015-09-24 15:55:37 -07:00
6 changed files with 182 additions and 1 deletions

View File

@@ -2294,10 +2294,17 @@ namespace ts {
return type && (type.flags & TypeFlags.Any) !== 0;
}
// Return the type of a binding element parent. We check SymbolLinks first to see if a type has been
// assigned by contextual typing.
function getTypeForBindingElementParent(node: VariableLikeDeclaration) {
let symbol = getSymbolOfNode(node);
return symbol && getSymbolLinks(symbol).type || getTypeForVariableLikeDeclaration(node);
}
// Return the inferred type for a binding element
function getTypeForBindingElement(declaration: BindingElement): Type {
let pattern = <BindingPattern>declaration.parent;
let parentType = getTypeForVariableLikeDeclaration(<VariableLikeDeclaration>pattern.parent);
let parentType = getTypeForBindingElementParent(<VariableLikeDeclaration>pattern.parent);
// If parent has the unknown (error) type, then so does this binding element
if (parentType === unknownType) {
return unknownType;
@@ -9163,10 +9170,24 @@ namespace ts {
}
}
// When contextual typing assigns a type to a parameter that contains a binding pattern, we also need to push
// the destructured type into the contained binding elements.
function assignBindingElementTypes(node: VariableLikeDeclaration) {
if (isBindingPattern(node.name)) {
for (let element of (<BindingPattern>node.name).elements) {
if (element.kind !== SyntaxKind.OmittedExpression) {
getSymbolLinks(getSymbolOfNode(element)).type = getTypeForBindingElement(element);
assignBindingElementTypes(element);
}
}
}
}
function assignTypeToParameterAndFixTypeParameters(parameter: Symbol, contextualType: Type, mapper: TypeMapper) {
let links = getSymbolLinks(parameter);
if (!links.type) {
links.type = instantiateType(contextualType, mapper);
assignBindingElementTypes(<ParameterDeclaration>parameter.valueDeclaration);
}
else if (isInferentialContext(mapper)) {
// Even if the parameter already has a type, it might be because it was given a type while