From 2564e1cd26428d3ec36d9db5b3c4aeb6800e2976 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 6 Nov 2016 12:38:49 -0800 Subject: [PATCH] Handle recursion in mapped type display --- src/compiler/checker.ts | 62 ++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fe895d5be45..5c171341e6c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2243,12 +2243,9 @@ namespace ts { else if (type.flags & TypeFlags.UnionOrIntersection) { writeUnionOrIntersectionType(type, nextFlags); } - else if (getObjectFlags(type) & ObjectFlags.Anonymous) { + else if (getObjectFlags(type) & (ObjectFlags.Anonymous | ObjectFlags.Mapped)) { writeAnonymousType(type, nextFlags); } - else if (getObjectFlags(type) & ObjectFlags.Mapped) { - writeMappedType(type); - } else if (type.flags & TypeFlags.StringOrNumberLiteral) { writer.writeStringLiteral(literalTypeToString(type)); } @@ -2465,6 +2462,13 @@ namespace ts { } function writeLiteralType(type: ObjectType, flags: TypeFormatFlags) { + if (type.objectFlags & ObjectFlags.Mapped) { + if (getConstraintTypeFromMappedType(type).flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { + writeMappedType(type); + return; + } + } + const resolved = resolveStructuredTypeMembers(type); if (!resolved.properties.length && !resolved.stringIndexInfo && !resolved.numberIndexInfo) { if (!resolved.callSignatures.length && !resolved.constructSignatures.length) { @@ -2541,36 +2545,30 @@ namespace ts { } function writeMappedType(type: MappedType) { - const constraintType = getConstraintTypeFromMappedType(type); - if (constraintType.flags & (TypeFlags.TypeParameter | TypeFlags.Index)) { - writePunctuation(writer, SyntaxKind.OpenBraceToken); - writer.writeLine(); - writer.increaseIndent(); - if (type.isReadonly) { - writeKeyword(writer, SyntaxKind.ReadonlyKeyword); - writeSpace(writer); - } - writePunctuation(writer, SyntaxKind.OpenBracketToken); - appendSymbolNameOnly(type.typeParameter.symbol, writer); + writePunctuation(writer, SyntaxKind.OpenBraceToken); + writer.writeLine(); + writer.increaseIndent(); + if (type.isReadonly) { + writeKeyword(writer, SyntaxKind.ReadonlyKeyword); writeSpace(writer); - writeKeyword(writer, SyntaxKind.InKeyword); - writeSpace(writer); - writeType(constraintType, TypeFormatFlags.None); - writePunctuation(writer, SyntaxKind.CloseBracketToken); - if (type.isOptional) { - writePunctuation(writer, SyntaxKind.QuestionToken); - } - writePunctuation(writer, SyntaxKind.ColonToken); - writeSpace(writer); - writeType(getTemplateTypeFromMappedType(type), TypeFormatFlags.None); - writePunctuation(writer, SyntaxKind.SemicolonToken); - writer.writeLine(); - writer.decreaseIndent(); - writePunctuation(writer, SyntaxKind.CloseBraceToken); } - else { - writeLiteralType(type, TypeFormatFlags.None); + writePunctuation(writer, SyntaxKind.OpenBracketToken); + appendSymbolNameOnly(type.typeParameter.symbol, writer); + writeSpace(writer); + writeKeyword(writer, SyntaxKind.InKeyword); + writeSpace(writer); + writeType(getConstraintTypeFromMappedType(type), TypeFormatFlags.None); + writePunctuation(writer, SyntaxKind.CloseBracketToken); + if (type.isOptional) { + writePunctuation(writer, SyntaxKind.QuestionToken); } + writePunctuation(writer, SyntaxKind.ColonToken); + writeSpace(writer); + writeType(getTemplateTypeFromMappedType(type), TypeFormatFlags.None); + writePunctuation(writer, SyntaxKind.SemicolonToken); + writer.writeLine(); + writer.decreaseIndent(); + writePunctuation(writer, SyntaxKind.CloseBraceToken); } } @@ -5935,7 +5933,7 @@ namespace ts { function getTypeFromMappedTypeNode(node: MappedTypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type { const links = getNodeLinks(node); if (!links.resolvedType) { - const type = createObjectType(ObjectFlags.Mapped); + const type = createObjectType(ObjectFlags.Mapped, node.symbol); type.typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)); type.templateType = node.type ? getTypeFromTypeNode(node.type) : anyType; type.isReadonly = !!node.readonlyToken;