@@ -13984,6 +13984,27 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1398413984 return isTypeAssignableTo(nameType, getTypeParameterFromMappedType(type)) ? MappedTypeNameTypeKind.Filtering : MappedTypeNameTypeKind.Remapping;
1398513985 }
1398613986
13987+ // generic mapped types that don't simplify or have a constraint still have a very simple set of keys - their nameType or constraintType.
13988+ // In many ways, this is a deferred version of what `getIndexTypeForMappedType` does to actually resolve the keys for _non_-generic types
13989+ function getGenericMappedTypeKeys(type: MappedType) {
13990+ const nameType = getNameTypeFromMappedType(type);
13991+ if (nameType && isMappedTypeWithKeyofConstraintDeclaration(type)) {
13992+ // we need to get the apparent mappings and union them with the generic mappings, since some properties may be
13993+ // missing from the `constraintType` which will otherwise be mapped in the object
13994+ const modifiersType = getApparentType(getModifiersTypeFromMappedType(type));
13995+ const mappedKeys: Type[] = [];
13996+ forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(
13997+ modifiersType,
13998+ TypeFlags.StringOrNumberLiteralOrUnique,
13999+ /*stringsOnly*/ false,
14000+ t => void mappedKeys.push(instantiateType(nameType, appendTypeMapping(type.mapper, getTypeParameterFromMappedType(type), t))),
14001+ );
14002+ // We still need to include the non-apparent (and thus still generic) keys since when this gets used in comparisons the other side might include them
14003+ return getUnionType([...mappedKeys, nameType]);
14004+ }
14005+ return nameType || getConstraintTypeFromMappedType(type);
14006+ }
14007+
1398714008 function resolveStructuredTypeMembers(type: StructuredType): ResolvedType {
1398814009 if (!(type as ResolvedType).members) {
1398914010 if (type.flags & TypeFlags.Object) {
@@ -22352,34 +22373,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2235222373 return Ternary.True;
2235322374 }
2235422375 }
22355- else if (isGenericMappedType(targetType)) {
22356- // generic mapped types that don't simplify or have a constraint still have a very simple set of keys we can compare against
22357- // - their nameType or constraintType.
22358- // In many ways, this comparison is a deferred version of what `getIndexTypeForMappedType` does to actually resolve the keys for _non_-generic types
22359-
22360- const nameType = getNameTypeFromMappedType(targetType);
22361- const constraintType = getConstraintTypeFromMappedType(targetType);
22362- let targetKeys;
22363- if (nameType && isMappedTypeWithKeyofConstraintDeclaration(targetType)) {
22364- // we need to get the apparent mappings and union them with the generic mappings, since some properties may be
22365- // missing from the `constraintType` which will otherwise be mapped in the object
22366- const modifiersType = getApparentType(getModifiersTypeFromMappedType(targetType));
22367- const mappedKeys: Type[] = [];
22368- forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(
22369- modifiersType,
22370- TypeFlags.StringOrNumberLiteralOrUnique,
22371- /*stringsOnly*/ false,
22372- t => void mappedKeys.push(instantiateType(nameType, appendTypeMapping(targetType.mapper, getTypeParameterFromMappedType(targetType), t))),
22373- );
22374- // We still need to include the non-apparent (and thus still generic) keys in the target side of the comparison (in case they're in the source side)
22375- targetKeys = getUnionType([...mappedKeys, nameType]);
22376- }
22377- else {
22378- targetKeys = nameType || constraintType;
22379- }
22380- if (isRelatedTo(source, targetKeys, RecursionFlags.Target, reportErrors) === Ternary.True) {
22381- return Ternary.True;
22382- }
22376+ else if (isGenericMappedType(targetType) && isRelatedTo(source, getGenericMappedTypeKeys(targetType), RecursionFlags.Target, reportErrors) === Ternary.True) {
22377+ return Ternary.True;
2238322378 }
2238422379 }
2238522380 }
@@ -22565,12 +22560,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2256522560 }
2256622561 }
2256722562 else if (sourceFlags & TypeFlags.Index) {
22568- const indexType = source as IndexType;
22569- let sourceKeys = keyofConstraintType;
22570- if (isGenericMappedType(indexType.type)) {
22571- sourceKeys = getMappedTypeNameTypeKind(indexType.type) !== MappedTypeNameTypeKind.None ? getNameTypeFromMappedType(indexType.type)! : getConstraintTypeFromMappedType(indexType.type);
22563+ const sourceType = (source as IndexType).type;
22564+ if (isGenericMappedType(sourceType) && isRelatedTo(getGenericMappedTypeKeys(sourceType), target, RecursionFlags.Source, reportErrors) === Ternary.True) {
22565+ return Ternary.True;
2257222566 }
22573- if (result = isRelatedTo(sourceKeys , target, RecursionFlags.Source, reportErrors)) {
22567+ if (result = isRelatedTo(keyofConstraintType , target, RecursionFlags.Source, reportErrors)) {
2257422568 return result;
2257522569 }
2257622570 }
0 commit comments