Add infer T constraint inference rule matching up mapped type templates across check/extends types (#43649)

This commit is contained in:
Wesley Wigham
2021-04-21 12:49:02 -07:00
committed by GitHub
parent a433c3c0ce
commit 8ea4ec9496
5 changed files with 110 additions and 0 deletions

View File

@@ -12613,6 +12613,19 @@ namespace ts {
else if (grandParent.kind === SyntaxKind.TypeParameter && grandParent.parent.kind === SyntaxKind.MappedType) {
inferences = append(inferences, keyofConstraintType);
}
// When an 'infer T' declaration is the template of a mapped type, and that mapped type if the extends
// clause of a conditional whose check type is also a mapped type, give it the constraint of the template
// of the check type's mapped type
else if (grandParent.kind === SyntaxKind.MappedType && (grandParent as MappedTypeNode).type &&
skipParentheses((grandParent as MappedTypeNode).type!) === declaration.parent && grandParent.parent.kind === SyntaxKind.ConditionalType &&
(grandParent.parent as ConditionalTypeNode).extendsType === grandParent && (grandParent.parent as ConditionalTypeNode).checkType.kind === SyntaxKind.MappedType &&
((grandParent.parent as ConditionalTypeNode).checkType as MappedTypeNode).type) {
const checkMappedType = (grandParent.parent as ConditionalTypeNode).checkType as MappedTypeNode;
const nodeType = getTypeFromTypeNode(checkMappedType.type!);
inferences = append(inferences, instantiateType(nodeType,
makeUnaryTypeMapper(getDeclaredTypeOfTypeParameter(getSymbolOfNode(checkMappedType.typeParameter)), checkMappedType.typeParameter.constraint ? getTypeFromTypeNode(checkMappedType.typeParameter.constraint) : keyofConstraintType)
));
}
}
}
}