Fixed symbol declarations for generic filtering mapped types (#53207)

This commit is contained in:
Mateusz Burzyński
2023-03-15 18:43:45 +01:00
committed by GitHub
parent 78089b4964
commit eb6aaea86e
2 changed files with 36 additions and 6 deletions

View File

@@ -13219,9 +13219,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// and T as the template type.
const typeParameter = getTypeParameterFromMappedType(type);
const constraintType = getConstraintTypeFromMappedType(type);
const nameType = getNameTypeFromMappedType(type.target as MappedType || type);
const isFilteringMappedType = nameType && isTypeAssignableTo(nameType, typeParameter);
const templateType = getTemplateTypeFromMappedType(type.target as MappedType || type);
const mappedType = (type.target as MappedType) || type;
const nameType = getNameTypeFromMappedType(mappedType);
const shouldLinkPropDeclarations = !nameType || isFilteringMappedType(mappedType);
const templateType = getTemplateTypeFromMappedType(mappedType);
const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
const templateModifiers = getMappedTypeModifiers(type);
const include = keyofStringsOnly ? TypeFlags.StringLiteral : TypeFlags.StringOrNumberLiteralOrUnique;
@@ -13267,7 +13268,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
prop.links.keyType = keyType;
if (modifiersProp) {
prop.links.syntheticOrigin = modifiersProp;
prop.declarations = !nameType || isFilteringMappedType ? modifiersProp.declarations : undefined;
prop.declarations = shouldLinkPropDeclarations ? modifiersProp.declarations : undefined;
}
members.set(propName, prop);
}
@@ -13400,6 +13401,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return false;
}
function isFilteringMappedType(type: MappedType): boolean {
const nameType = getNameTypeFromMappedType(type);
return !!nameType && isTypeAssignableTo(nameType, getTypeParameterFromMappedType(type));
}
function resolveStructuredTypeMembers(type: StructuredType): ResolvedType {
if (!(type as ResolvedType).members) {
if (type.flags & TypeFlags.Object) {
@@ -17528,8 +17534,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// K is generic and N is assignable to P, instantiate E using a mapper that substitutes the index type for P.
// For example, for an index access { [P in K]: Box<T[P]> }[X], we construct the type Box<T[X]>.
if (isGenericMappedType(objectType)) {
const nameType = getNameTypeFromMappedType(objectType);
if (!nameType || isTypeAssignableTo(nameType, getTypeParameterFromMappedType(objectType))) {
if (!getNameTypeFromMappedType(objectType) || isFilteringMappedType(objectType)) {
return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), t => getSimplifiedType(t, writing));
}
}