Skip to content

Commit fcdaa91

Browse files
committed
remove getApparentMappedTypeKeys on the source side
1 parent 21f4f7c commit fcdaa91

1 file changed

Lines changed: 13 additions & 18 deletions

File tree

src/compiler/checker.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23464,22 +23464,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2346423464
return result;
2346523465
}
2346623466

23467-
function getApparentMappedTypeKeys(nameType: Type, mappedType: MappedType, forSource: boolean) {
23468-
const modifiersType = getApparentType(getModifiersTypeFromMappedType(mappedType));
23467+
function getApparentTargetMappedTypeKeys(nameType: Type, targetType: MappedType) {
23468+
const modifiersType = getApparentType(getModifiersTypeFromMappedType(targetType));
2346923469
const mappedKeys: Type[] = [];
2347023470
forEachMappedTypePropertyKeyTypeAndIndexSignatureKeyType(
2347123471
modifiersType,
2347223472
TypeFlags.StringOrNumberLiteralOrUnique,
2347323473
/*stringsOnly*/ false,
23474-
t => void mappedKeys.push(instantiateType(nameType, appendTypeMapping(mappedType.mapper, getTypeParameterFromMappedType(mappedType), t))),
23474+
t => void mappedKeys.push(instantiateType(nameType, appendTypeMapping(targetType.mapper, getTypeParameterFromMappedType(targetType), t))),
2347523475
);
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;
23476+
return getUnionType(mappedKeys);
2348323477
}
2348423478

2348523479
function structuredTypeRelatedToWorker(source: Type, target: Type, reportErrors: boolean, intersectionState: IntersectionState, saveErrorInfo: ReturnType<typeof captureErrorCalculationState>): Ternary {
@@ -23632,6 +23626,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2363223626
return result;
2363323627
}
2363423628
}
23629+
if (sourceFlags & TypeFlags.TypeParameter && source.symbol && some(source.symbol.declarations, d => d.parent.kind === SyntaxKind.MappedType)) {
23630+
const constraint = getConstraintOfTypeParameter(source);
23631+
if (constraint && isRelatedTo(constraint, target, RecursionFlags.Both, /*reportErrors*/ false) === Ternary.True) {
23632+
return Ternary.True;
23633+
}
23634+
}
2363523635
if (isTupleType(targetType)) {
2363623636
// An index type can have a tuple type target when the tuple type contains variadic elements.
2363723637
// Check if the source is related to the known keys of the tuple type.
@@ -23663,7 +23663,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2366323663
if (nameType && isMappedTypeWithKeyofConstraintDeclaration(targetType)) {
2366423664
// we need to get the apparent mappings and union them with the generic mappings, since some properties may be
2366523665
// missing from the `constraintType` which will otherwise be mapped in the object
23666-
const mappedKeys = getApparentMappedTypeKeys(nameType, targetType, /*forSource*/ false);
23666+
const mappedKeys = getApparentTargetMappedTypeKeys(nameType, targetType);
2366723667
// 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)
2366823668
targetKeys = getUnionType([mappedKeys, nameType]);
2366923669
}
@@ -23865,12 +23865,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2386523865
if (isDeferredMappedIndex) {
2386623866
const mappedType = (source as IndexType).type as MappedType;
2386723867
const nameType = getNameTypeFromMappedType(mappedType);
23868-
// Unlike on the target side, on the source side we do *not* include the generic part of the `nameType`, since that comes from a
23869-
// (potentially anonymous) mapped type local type parameter, so that'd never assign outside the mapped type body, but we still want to
23870-
// allow assignments of index types of identical (or similar enough) mapped types.
23871-
// 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`).
23872-
// 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.
23873-
const sourceMappedKeys = nameType && isMappedTypeWithKeyofConstraintDeclaration(mappedType) ? getApparentMappedTypeKeys(nameType, mappedType, /*forSource*/ true) : (nameType || getConstraintTypeFromMappedType(mappedType));
23868+
const sourceMappedKeys = nameType || getConstraintTypeFromMappedType(mappedType);
2387423869
if (result = isRelatedTo(sourceMappedKeys, target, RecursionFlags.Source, reportErrors)) {
2387523870
return result;
2387623871
}
@@ -24117,7 +24112,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2411724112
const sourceConstraint = instantiateType(getConstraintTypeFromMappedType(source), getCombinedMappedTypeOptionality(source) < 0 ? reportUnmeasurableMapper : reportUnreliableMapper);
2411824113
if (result = isRelatedTo(targetConstraint, sourceConstraint, RecursionFlags.Both, reportErrors)) {
2411924114
const mapper = createTypeMapper([getTypeParameterFromMappedType(source)], [getTypeParameterFromMappedType(target)]);
24120-
if (instantiateType(getNameTypeFromMappedType(source), mapper) === instantiateType(getNameTypeFromMappedType(target), mapper)) {
24115+
if (isTypeIdenticalTo(instantiateType(getNameTypeFromMappedType(source), mapper) ?? unknownType, instantiateType(getNameTypeFromMappedType(target), mapper) ?? unknownType)) {
2412124116
return result & isRelatedTo(instantiateType(getTemplateTypeFromMappedType(source), mapper), getTemplateTypeFromMappedType(target), RecursionFlags.Both, reportErrors);
2412224117
}
2412324118
}

0 commit comments

Comments
 (0)