From 5de63a74eb896265a9c948080d5dd8fc4960877f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 7 Nov 2016 09:43:01 -0800 Subject: [PATCH] Validate constraint type in mapped type --- src/compiler/checker.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5c171341e6c..94d5a393fea 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5933,14 +5933,22 @@ namespace ts { function getTypeFromMappedTypeNode(node: MappedTypeNode, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type { const links = getNodeLinks(node); if (!links.resolvedType) { - 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; - type.isOptional = !!node.questionToken; - type.aliasSymbol = aliasSymbol; - type.aliasTypeArguments = aliasTypeArguments; - links.resolvedType = type; + const typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node.typeParameter)); + const constraintType = getConstraintOfTypeParameter(typeParameter); + const keyType = constraintType && constraintType.flags & TypeFlags.TypeParameter ? getApparentType(constraintType) : constraintType; + if (keyType && (keyType.flags & TypeFlags.Index || checkTypeAssignableTo(keyType, stringOrNumberType, node.typeParameter.constraint))) { + const type = createObjectType(ObjectFlags.Mapped, node.symbol); + type.typeParameter = typeParameter; + type.templateType = node.type ? getTypeFromTypeNode(node.type) : unknownType; + type.isReadonly = !!node.readonlyToken; + type.isOptional = !!node.questionToken; + type.aliasSymbol = aliasSymbol; + type.aliasTypeArguments = aliasTypeArguments; + links.resolvedType = type; + } + else { + links.resolvedType = unknownType; + } } return links.resolvedType; }