Skip to content

Commit 8f5ef10

Browse files
committed
Don't infer from initializers of parameters of contextually typed functions
1 parent 3a2f6a3 commit 8f5ef10

File tree

1 file changed

+13
-18
lines changed

1 file changed

+13
-18
lines changed

src/compiler/checker.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4862,17 +4862,8 @@ namespace ts {
48624862
function getTypeForBindingElement(declaration: BindingElement): Type | undefined {
48634863
const pattern = declaration.parent;
48644864
let parentType = getTypeForBindingElementParent(pattern.parent);
4865-
// If parent has the unknown (error) type, then so does this binding element
4866-
if (parentType === errorType) {
4867-
return errorType;
4868-
}
4869-
// If no type was specified or inferred for parent,
4870-
// infer from the initializer of the binding element if one is present.
4871-
// Otherwise, go with the undefined type of the parent.
4872-
if (!parentType) {
4873-
return declaration.initializer ? checkDeclarationInitializer(declaration) : parentType;
4874-
}
4875-
if (isTypeAny(parentType)) {
4865+
// If no type or an any type was inferred for parent, infer that for the binding element
4866+
if (!parentType || isTypeAny(parentType)) {
48764867
return parentType;
48774868
}
48784869
// Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation
@@ -5041,8 +5032,11 @@ namespace ts {
50415032
}
50425033
}
50435034

5044-
// Use the type of the initializer expression if one is present
5045-
if (declaration.initializer) {
5035+
const isParameterOfContextuallyTypedFunction = declaration.kind === SyntaxKind.Parameter && getContextualType(<Expression>declaration.parent);
5036+
5037+
// Use the type of the initializer expression if one is present and the declaration is
5038+
// not a parameter of a contextually typed function
5039+
if (declaration.initializer && !isParameterOfContextuallyTypedFunction) {
50465040
const type = checkDeclarationInitializer(declaration);
50475041
return addOptionality(type, isOptional);
50485042
}
@@ -5053,8 +5047,9 @@ namespace ts {
50535047
return trueType;
50545048
}
50555049

5056-
// If the declaration specifies a binding pattern, use the type implied by the binding pattern
5057-
if (isBindingPattern(declaration.name)) {
5050+
// If the declaration specifies a binding pattern and is not a parameter of a contextually
5051+
// typed function, use the type implied by the binding pattern
5052+
if (isBindingPattern(declaration.name) && !isParameterOfContextuallyTypedFunction) {
50585053
return getTypeFromBindingPattern(declaration.name, /*includePatternInType*/ false, /*reportErrors*/ true);
50595054
}
50605055

@@ -25638,13 +25633,13 @@ namespace ts {
2563825633
const parent = node.parent.parent;
2563925634
const parentType = getTypeForBindingElementParent(parent);
2564025635
const name = node.propertyName || node.name;
25641-
if (!isBindingPattern(name)) {
25636+
if (parentType && !isBindingPattern(name)) {
2564225637
const nameText = getTextOfPropertyName(name);
2564325638
if (nameText) {
25644-
const property = getPropertyOfType(parentType!, nameText); // TODO: GH#18217
25639+
const property = getPropertyOfType(parentType, nameText);
2564525640
if (property) {
2564625641
markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
25647-
checkPropertyAccessibility(parent, !!parent.initializer && parent.initializer.kind === SyntaxKind.SuperKeyword, parentType!, property);
25642+
checkPropertyAccessibility(parent, !!parent.initializer && parent.initializer.kind === SyntaxKind.SuperKeyword, parentType, property);
2564825643
}
2564925644
}
2565025645
}

0 commit comments

Comments
 (0)