Implicit constraints in non-distributive '[T] extends [U] ? X : Y' types

This commit is contained in:
Anders Hejlsberg
2018-03-20 14:08:05 -07:00
parent 56710dd537
commit 420e58c444

View File

@@ -7349,13 +7349,24 @@ namespace ts {
return result;
}
function isUnaryTupleTypeNode(node: TypeNode) {
return node.kind === SyntaxKind.TupleType && (<TupleTypeNode>node).elementTypes.length === 1;
}
function getImpliedConstraint(typeVariable: TypeVariable, checkNode: TypeNode, extendsNode: TypeNode): Type {
return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, (<TupleTypeNode>checkNode).elementTypes[0], (<TupleTypeNode>extendsNode).elementTypes[0]) :
getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) :
undefined;
}
function getConstrainedTypeVariable(typeVariable: TypeVariable, node: Node) {
let constraints: Type[];
while (isPartOfTypeNode(node)) {
const parent = node.parent;
if (parent.kind === SyntaxKind.ConditionalType && node === (<ConditionalTypeNode>parent).trueType) {
if (getActualTypeVariable(getTypeFromTypeNode((<ConditionalTypeNode>parent).checkType)) === typeVariable) {
constraints = append(constraints, getTypeFromTypeNode((<ConditionalTypeNode>parent).extendsType));
const constraint = getImpliedConstraint(typeVariable, (<ConditionalTypeNode>parent).checkType, (<ConditionalTypeNode>parent).extendsType);
if (constraint) {
constraints = append(constraints, constraint);
}
}
node = parent;