@@ -4536,15 +4536,27 @@ namespace ts {
4536
4536
const typeParameter = getTypeParameterFromMappedType(type);
4537
4537
const constraintType = getConstraintTypeFromMappedType(type);
4538
4538
const templateType = getTemplateTypeFromMappedType(type);
4539
- const modifiersType = getModifiersTypeFromMappedType(type);
4539
+ const modifiersType = getApparentType( getModifiersTypeFromMappedType(type) );
4540
4540
const templateReadonly = !!type.declaration.readonlyToken;
4541
4541
const templateOptional = !!type.declaration.questionToken;
4542
- // First, if the constraint type is a type parameter, obtain the base constraint. Then,
4543
- // if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
4544
- // Finally, iterate over the constituents of the resulting iteration type.
4545
- const keyType = constraintType.flags & TypeFlags.TypeVariable ? getApparentType(constraintType) : constraintType;
4546
- const iterationType = keyType.flags & TypeFlags.Index ? getIndexType(getApparentType((<IndexType>keyType).type)) : keyType;
4547
- forEachType(iterationType, t => {
4542
+ if (type.declaration.typeParameter.constraint.kind === SyntaxKind.TypeOperator) {
4543
+ // We have a { [P in keyof T]: X }
4544
+ forEachType(getLiteralTypeFromPropertyNames(modifiersType), addMemberForKeyType);
4545
+ if (getIndexInfoOfType(modifiersType, IndexKind.String)) {
4546
+ addMemberForKeyType(stringType);
4547
+ }
4548
+ }
4549
+ else {
4550
+ // First, if the constraint type is a type parameter, obtain the base constraint. Then,
4551
+ // if the key type is a 'keyof X', obtain 'keyof C' where C is the base constraint of X.
4552
+ // Finally, iterate over the constituents of the resulting iteration type.
4553
+ const keyType = constraintType.flags & TypeFlags.TypeVariable ? getApparentType(constraintType) : constraintType;
4554
+ const iterationType = keyType.flags & TypeFlags.Index ? getIndexType(getApparentType((<IndexType>keyType).type)) : keyType;
4555
+ forEachType(iterationType, addMemberForKeyType);
4556
+ }
4557
+ setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
4558
+
4559
+ function addMemberForKeyType(t: Type) {
4548
4560
// Create a mapper from T to the current iteration type constituent. Then, if the
4549
4561
// mapped type is itself an instantiated type, combine the iteration mapper with the
4550
4562
// instantiation mapper.
@@ -4565,8 +4577,7 @@ namespace ts {
4565
4577
else if (t.flags & TypeFlags.String) {
4566
4578
stringIndexInfo = createIndexInfo(propType, templateReadonly);
4567
4579
}
4568
- });
4569
- setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
4580
+ }
4570
4581
}
4571
4582
4572
4583
function getTypeParameterFromMappedType(type: MappedType) {
0 commit comments