Skip to content

Commit 21f4f7c

Browse files
committed
move the fix to getApparentMappedTypeKeys
1 parent 05cc6dd commit 21f4f7c

File tree

1 file changed

+10
-15
lines changed

1 file changed

+10
-15
lines changed

src/compiler/checker.ts

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}
@@ -23864,18 +23870,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2386423870
// allow assignments of index types of identical (or similar enough) mapped types.
2386523871
// eg, `keyof {[X in keyof A]: Obj[X]}` should be assignable to `keyof {[Y in keyof A]: Tup[Y]}` because both map over the same set of keys (`keyof A`).
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.
23867-
let sourceMappedKeys: Type;
23868-
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-
}
23876-
else {
23877-
sourceMappedKeys = nameType || getConstraintTypeFromMappedType(mappedType);
23878-
}
23873+
const sourceMappedKeys = nameType && isMappedTypeWithKeyofConstraintDeclaration(mappedType) ? getApparentMappedTypeKeys(nameType, mappedType, /*forSource*/ true) : (nameType || getConstraintTypeFromMappedType(mappedType));
2387923874
if (result = isRelatedTo(sourceMappedKeys, target, RecursionFlags.Source, reportErrors)) {
2388023875
return result;
2388123876
}

0 commit comments

Comments
 (0)