diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 509c2981908..d865df5cfd5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2893,7 +2893,8 @@ namespace ts { flags, tracker: tracker && tracker.trackSymbol ? tracker : { trackSymbol: noop }, encounteredError: false, - symbolStack: undefined + symbolStack: undefined, + inferTypeParameters: undefined }; } @@ -2985,6 +2986,9 @@ namespace ts { return typeReferenceToTypeNode(type); } if (type.flags & TypeFlags.TypeParameter || objectFlags & ObjectFlags.ClassOrInterface) { + if (type.flags & TypeFlags.TypeParameter && contains(context.inferTypeParameters, type)) { + return createInferTypeNode(createTypeParameterDeclaration(getNameOfSymbolAsWritten(type.symbol))); + } const name = type.symbol ? symbolToName(type.symbol, context, SymbolFlags.Type, /*expectsIdentifier*/ false) : createIdentifier("?"); // Ignore constraint/default when creating a usage (as opposed to declaration) of a type parameter. return createTypeReferenceNode(name, /*typeArguments*/ undefined); @@ -3025,7 +3029,10 @@ namespace ts { } if (type.flags & TypeFlags.Conditional) { const checkTypeNode = typeToTypeNodeHelper((type).checkType, context); + const saveInferTypeParameters = context.inferTypeParameters; + context.inferTypeParameters = (type).root.inferTypeParameters; const extendsTypeNode = typeToTypeNodeHelper((type).extendsType, context); + context.inferTypeParameters = saveInferTypeParameters; const trueTypeNode = typeToTypeNodeHelper(getTrueTypeFromConditionalType(type), context); const falseTypeNode = typeToTypeNodeHelper(getFalseTypeFromConditionalType(type), context); return createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode); @@ -3694,6 +3701,7 @@ namespace ts { // State encounteredError: boolean; symbolStack: Symbol[] | undefined; + inferTypeParameters: TypeParameter[] | undefined; } function isDefaultBindingContext(location: Node) { @@ -20616,7 +20624,8 @@ namespace ts { } function checkInferType(node: InferTypeNode) { - if (!findAncestor(node, n => n.parent && n.parent.kind === SyntaxKind.ConditionalType && (n.parent).extendsType === n)) { + const ancestor = findAncestor(node, n => n.parent && n.parent.kind === SyntaxKind.ConditionalType); + if (!ancestor || (ancestor.parent).extendsType !== ancestor) { grammarErrorOnNode(node, Diagnostics.infer_declarations_are_only_permitted_in_the_extends_clause_of_a_conditional_type); } checkSourceElement(node.typeParameter);