@@ -2620,6 +2620,13 @@ namespace ts {
26202620 const indexTypeNode = typeToTypeNodeHelper((<IndexedAccessType>type).indexType, context);
26212621 return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
26222622 }
2623+ if (type.flags & TypeFlags.Conditional) {
2624+ const checkTypeNode = typeToTypeNodeHelper((<ConditionalType>type).checkType, context);
2625+ const extendskTypeNode = typeToTypeNodeHelper((<ConditionalType>type).extendsType, context);
2626+ const trueTypeNode = typeToTypeNodeHelper((<ConditionalType>type).trueType, context);
2627+ const falseTypeNode = typeToTypeNodeHelper((<ConditionalType>type).falseType, context);
2628+ return createConditionalTypeNode(checkTypeNode, extendskTypeNode, trueTypeNode, falseTypeNode);
2629+ }
26232630
26242631 Debug.fail("Should be unreachable.");
26252632
@@ -3388,6 +3395,15 @@ namespace ts {
33883395 writeType((<IndexedAccessType>type).indexType, TypeFormatFlags.None);
33893396 writePunctuation(writer, SyntaxKind.CloseBracketToken);
33903397 }
3398+ else if (type.flags & TypeFlags.Conditional) {
3399+ writeType((<ConditionalType>type).checkType, TypeFormatFlags.InElementType);
3400+ writer.writeKeyword("extends");
3401+ writeType((<ConditionalType>type).extendsType, TypeFormatFlags.InElementType);
3402+ writePunctuation(writer, SyntaxKind.QuestionToken);
3403+ writeType((<ConditionalType>type).trueType, TypeFormatFlags.InElementType);
3404+ writePunctuation(writer, SyntaxKind.ColonToken);
3405+ writeType((<ConditionalType>type).falseType, TypeFormatFlags.InElementType);
3406+ }
33913407 else {
33923408 // Should never get here
33933409 // { ... }
@@ -8189,6 +8205,35 @@ namespace ts {
81898205 return links.resolvedType;
81908206 }
81918207
8208+ function getConditionalType(checkType: Type, extendsType: Type, trueType: Type, falseType: Type, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
8209+ if (checkType.flags & TypeFlags.Union) {
8210+ return getUnionType(map((<UnionType>checkType).types, t => getConditionalType(t, extendsType, trueType, falseType)),
8211+ /*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
8212+ }
8213+ if (isTypeAssignableTo(checkType, extendsType)) {
8214+ return trueType;
8215+ }
8216+ if (!isGenericObjectType(checkType) && !isGenericObjectType(extendsType)) {
8217+ return falseType;
8218+ }
8219+ const type = <ConditionalType>createType(TypeFlags.Conditional);
8220+ type.checkType = checkType;
8221+ type.extendsType = extendsType;
8222+ type.trueType = trueType;
8223+ type.falseType = falseType;
8224+ return type;
8225+ }
8226+
8227+ function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type {
8228+ const links = getNodeLinks(node);
8229+ if (!links.resolvedType) {
8230+ links.resolvedType = getConditionalType(getTypeFromTypeNode(node.checkType), getTypeFromTypeNode(node.extendsType),
8231+ getTypeFromTypeNode(node.trueType), getTypeFromTypeNode(node.falseType),
8232+ getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
8233+ }
8234+ return links.resolvedType;
8235+ }
8236+
81928237 function getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node: TypeNode): Type {
81938238 const links = getNodeLinks(node);
81948239 if (!links.resolvedType) {
@@ -8481,6 +8526,8 @@ namespace ts {
84818526 return getTypeFromIndexedAccessTypeNode(<IndexedAccessTypeNode>node);
84828527 case SyntaxKind.MappedType:
84838528 return getTypeFromMappedTypeNode(<MappedTypeNode>node);
8529+ case SyntaxKind.ConditionalType:
8530+ return getTypeFromConditionalTypeNode(<ConditionalTypeNode>node);
84848531 // This function assumes that an identifier or qualified name is a type expression
84858532 // Callers should first ensure this by calling isTypeNode
84868533 case SyntaxKind.Identifier:
@@ -8778,6 +8825,11 @@ namespace ts {
87788825 if (type.flags & TypeFlags.IndexedAccess) {
87798826 return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
87808827 }
8828+ if (type.flags & TypeFlags.Conditional) {
8829+ return getConditionalType(instantiateType((<ConditionalType>type).checkType, mapper), instantiateType((<ConditionalType>type).extendsType, mapper),
8830+ instantiateType((<ConditionalType>type).trueType, mapper), instantiateType((<ConditionalType>type).falseType, mapper),
8831+ type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
8832+ }
87818833 }
87828834 return type;
87838835 }
0 commit comments