@@ -4577,12 +4577,22 @@ namespace ts {
4577
4577
4578
4578
function getModifiersTypeFromMappedType(type: MappedType) {
4579
4579
if (!type.modifiersType) {
4580
- // If the mapped type was declared as { [P in keyof T]: X } or as { [P in K]: X }, where
4581
- // K is constrained to 'K extends keyof T', then we will copy property modifiers from T.
4582
- const declaredType = <MappedType>getTypeFromMappedTypeNode(type.declaration);
4583
- const constraint = getConstraintTypeFromMappedType(declaredType);
4584
- const extendedConstraint = constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>constraint) : constraint;
4585
- type.modifiersType = extendedConstraint.flags & TypeFlags.Index ? instantiateType((<IndexType>extendedConstraint).type, type.mapper || identityMapper) : emptyObjectType;
4580
+ const constraintDeclaration = type.declaration.typeParameter.constraint;
4581
+ if (constraintDeclaration.kind === SyntaxKind.TypeOperator) {
4582
+ // If the constraint declaration is a 'keyof T' node, the modifiers type is T. We check
4583
+ // AST nodes here because, when T is a non-generic type, the logic below eagerly resolves
4584
+ // 'keyof T' to a literal union type and we can't recover T from that type.
4585
+ type.modifiersType = instantiateType(getTypeFromTypeNode((<TypeOperatorNode>constraintDeclaration).type), type.mapper || identityMapper);
4586
+ }
4587
+ else {
4588
+ // Otherwise, get the declared constraint type, and if the constraint type is a type parameter,
4589
+ // get the constraint of that type parameter. If the resulting type is an indexed type 'keyof T',
4590
+ // the modifiers type is T. Otherwise, the modifiers type is {}.
4591
+ const declaredType = <MappedType>getTypeFromMappedTypeNode(type.declaration);
4592
+ const constraint = getConstraintTypeFromMappedType(declaredType);
4593
+ const extendedConstraint = constraint.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>constraint) : constraint;
4594
+ type.modifiersType = extendedConstraint.flags & TypeFlags.Index ? instantiateType((<IndexType>extendedConstraint).type, type.mapper || identityMapper) : emptyObjectType;
4595
+ }
4586
4596
}
4587
4597
return type.modifiersType;
4588
4598
}
0 commit comments