@@ -23464,7 +23464,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2346423464 return result;
2346523465 }
2346623466
23467- function getApparentMappedTypeKeys(nameType: Type, mappedType: MappedType) {
23467+ function getApparentMappedTypeKeys(nameType: Type, mappedType: MappedType, forSource: boolean ) {
2346823468 const modifiersType = getApparentType(getModifiersTypeFromMappedType(mappedType));
2346923469 const mappedKeys: Type[] = [];
2347023470 forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(
@@ -23473,7 +23473,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2347323473 /*stringsOnly*/ false,
2347423474 t => void mappedKeys.push(instantiateType(nameType, appendTypeMapping(mappedType.mapper, getTypeParameterFromMappedType(mappedType), t))),
2347523475 );
23476- return getUnionType(mappedKeys);
23476+ const apparentKeys = getUnionType(mappedKeys);
23477+ if (forSource && apparentKeys.flags & TypeFlags.Never) {
23478+ // modifiers type of mapped type is often `unknown`, `keyof unknown` is `never` and that's assignable to everything
23479+ // letting this through is too permissive so we use the apparent type of an index type here instead
23480+ return stringNumberSymbolType;
23481+ }
23482+ return apparentKeys;
2347723483 }
2347823484
2347923485 function structuredTypeRelatedToWorker(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState, saveErrorInfo: ReturnType<typeof captureErrorCalculationState>): Ternary {
@@ -23657,7 +23663,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2365723663 if (nameType && isMappedTypeWithKeyofConstraintDeclaration(targetType)) {
2365823664 // we need to get the apparent mappings and union them with the generic mappings, since some properties may be
2365923665 // missing from the `constraintType` which will otherwise be mapped in the object
23660- const mappedKeys = getApparentMappedTypeKeys(nameType, targetType);
23666+ const mappedKeys = getApparentMappedTypeKeys(nameType, targetType, /*forSource*/ false );
2366123667 // 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)
2366223668 targetKeys = getUnionType([mappedKeys, nameType]);
2366323669 }
@@ -23866,12 +23872,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2386623872 // Without this source-side breakdown, a `keyof {[X in keyof A]: Obj[X]}` style type won't be assignable to anything except itself, which is much too strict.
2386723873 let sourceMappedKeys: Type;
2386823874 if (nameType && isMappedTypeWithKeyofConstraintDeclaration(mappedType)) {
23869- sourceMappedKeys = getApparentMappedTypeKeys(nameType, mappedType);
23870- if (sourceMappedKeys.flags & TypeFlags.Never) {
23871- // modifiers type of mapped type is often `unknown`, `keyof unknown` is `never` and that's assignable to everything
23872- // letting this through is too permissive so we use the apparent type of an index type here instead
23873- sourceMappedKeys = stringNumberSymbolType;
23874- }
23875+ sourceMappedKeys = getApparentMappedTypeKeys(nameType, mappedType, /*forSource*/ true);
2387523876 }
2387623877 else {
2387723878 sourceMappedKeys = nameType || getConstraintTypeFromMappedType(mappedType);
0 commit comments