From 420e58c44462a415dab0480779dc574067074a7c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 20 Mar 2018 14:08:05 -0700 Subject: [PATCH] Implicit constraints in non-distributive '[T] extends [U] ? X : Y' types --- src/compiler/checker.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e8128fa4890..3876917bd2d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7349,13 +7349,24 @@ namespace ts { return result; } + function isUnaryTupleTypeNode(node: TypeNode) { + return node.kind === SyntaxKind.TupleType && (node).elementTypes.length === 1; + } + + function getImpliedConstraint(typeVariable: TypeVariable, checkNode: TypeNode, extendsNode: TypeNode): Type { + return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, (checkNode).elementTypes[0], (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 === (parent).trueType) { - if (getActualTypeVariable(getTypeFromTypeNode((parent).checkType)) === typeVariable) { - constraints = append(constraints, getTypeFromTypeNode((parent).extendsType)); + const constraint = getImpliedConstraint(typeVariable, (parent).checkType, (parent).extendsType); + if (constraint) { + constraints = append(constraints, constraint); } } node = parent;