Fixed apparent type of homomorphic mapped type with non-homomorphic instantiation (#56727)

This commit is contained in:
Mateusz Burzyński
2024-01-09 20:13:50 +01:00
committed by GitHub
parent 1e00399a38
commit 424b96475e
4 changed files with 252 additions and 5 deletions

View File

@@ -2049,6 +2049,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
var noConstraintType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray);
var circularConstraintType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray);
var resolvingDefaultType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray);
var resolvingApparentMappedType = createAnonymousType(/*symbol*/ undefined, emptySymbols, emptyArray, emptyArray, emptyArray);
var markerSuperType = createTypeParameter();
var markerSubType = createTypeParameter();
@@ -14459,15 +14460,32 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function getApparentTypeOfMappedType(type: MappedType) {
return type.resolvedApparentType || (type.resolvedApparentType = getResolvedApparentTypeOfMappedType(type));
if (type.resolvedApparentType) {
if (type.resolvedApparentType === resolvingApparentMappedType) {
return type.resolvedApparentType = type;
}
return type.resolvedApparentType;
}
type.resolvedApparentType = resolvingApparentMappedType;
return type.resolvedApparentType = getResolvedApparentTypeOfMappedType(type);
}
function getResolvedApparentTypeOfMappedType(type: MappedType) {
const typeVariable = getHomomorphicTypeVariable(type);
if (typeVariable && !type.declaration.nameType) {
const constraint = getConstraintOfTypeParameter(typeVariable);
const mappedType = type.target as MappedType || type;
const typeVariable = getHomomorphicTypeVariable(mappedType);
if (typeVariable && !mappedType.declaration.nameType) {
let constraint: Type | undefined;
if (!type.target) {
constraint = getConstraintOfTypeParameter(typeVariable);
}
else {
const modifiersConstraint = getConstraintOfType(getModifiersTypeFromMappedType(type));
if (modifiersConstraint) {
constraint = getApparentType(modifiersConstraint);
}
}
if (constraint && everyType(constraint, isArrayOrTupleType)) {
return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
return instantiateType(mappedType, prependTypeMapping(typeVariable, constraint, mappedType.mapper));
}
}
return type;