mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-11 10:46:28 -05:00
Defer index types on remapping mapped types (#55140)
Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
3258d75169
commit
2c4cbd98fa
@@ -1304,6 +1304,12 @@ const enum MappedTypeModifiers {
|
||||
ExcludeOptional = 1 << 3,
|
||||
}
|
||||
|
||||
const enum MappedTypeNameTypeKind {
|
||||
None,
|
||||
Filtering,
|
||||
Remapping,
|
||||
}
|
||||
|
||||
const enum ExpandingFlags {
|
||||
None = 0,
|
||||
Source = 1,
|
||||
@@ -13741,7 +13747,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
const constraintType = getConstraintTypeFromMappedType(type);
|
||||
const mappedType = (type.target as MappedType) || type;
|
||||
const nameType = getNameTypeFromMappedType(mappedType);
|
||||
const shouldLinkPropDeclarations = !nameType || isFilteringMappedType(mappedType);
|
||||
const shouldLinkPropDeclarations = getMappedTypeNameTypeKind(mappedType) !== MappedTypeNameTypeKind.Remapping;
|
||||
const templateType = getTemplateTypeFromMappedType(mappedType);
|
||||
const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T'
|
||||
const templateModifiers = getMappedTypeModifiers(type);
|
||||
@@ -13923,9 +13929,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return false;
|
||||
}
|
||||
|
||||
function isFilteringMappedType(type: MappedType): boolean {
|
||||
function getMappedTypeNameTypeKind(type: MappedType): MappedTypeNameTypeKind {
|
||||
const nameType = getNameTypeFromMappedType(type);
|
||||
return !!nameType && isTypeAssignableTo(nameType, getTypeParameterFromMappedType(type));
|
||||
if (!nameType) {
|
||||
return MappedTypeNameTypeKind.None;
|
||||
}
|
||||
return isTypeAssignableTo(nameType, getTypeParameterFromMappedType(type)) ? MappedTypeNameTypeKind.Filtering : MappedTypeNameTypeKind.Remapping;
|
||||
}
|
||||
|
||||
function resolveStructuredTypeMembers(type: StructuredType): ResolvedType {
|
||||
@@ -17700,7 +17709,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function shouldDeferIndexType(type: Type, indexFlags = IndexFlags.None) {
|
||||
return !!(type.flags & TypeFlags.InstantiableNonPrimitive ||
|
||||
isGenericTupleType(type) ||
|
||||
isGenericMappedType(type) && !hasDistributiveNameType(type) ||
|
||||
isGenericMappedType(type) && (!hasDistributiveNameType(type) || getMappedTypeNameTypeKind(type) === MappedTypeNameTypeKind.Remapping) ||
|
||||
type.flags & TypeFlags.Union && !(indexFlags & IndexFlags.NoReducibleCheck) && isGenericReducibleType(type) ||
|
||||
type.flags & TypeFlags.Intersection && maybeTypeOfKind(type, TypeFlags.Instantiable) && some((type as IntersectionType).types, isEmptyAnonymousObjectType));
|
||||
}
|
||||
@@ -18282,7 +18291,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)) {
|
||||
if (!getNameTypeFromMappedType(objectType) || isFilteringMappedType(objectType)) {
|
||||
if (getMappedTypeNameTypeKind(objectType) !== MappedTypeNameTypeKind.Remapping) {
|
||||
return type[cache] = mapType(substituteIndexedMappedType(objectType, type.indexType), t => getSimplifiedType(t, writing));
|
||||
}
|
||||
}
|
||||
@@ -40108,7 +40117,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
// Check if the index type is assignable to 'keyof T' for the object type.
|
||||
const objectType = (type as IndexedAccessType).objectType;
|
||||
const indexType = (type as IndexedAccessType).indexType;
|
||||
if (isTypeAssignableTo(indexType, getIndexType(objectType, IndexFlags.None))) {
|
||||
// skip index type deferral on remapping mapped types
|
||||
const objectIndexType = isGenericMappedType(objectType) && getMappedTypeNameTypeKind(objectType) === MappedTypeNameTypeKind.Remapping
|
||||
? getIndexTypeForMappedType(objectType, IndexFlags.None)
|
||||
: getIndexType(objectType, IndexFlags.None);
|
||||
if (isTypeAssignableTo(indexType, objectIndexType)) {
|
||||
if (
|
||||
accessNode.kind === SyntaxKind.ElementAccessExpression && isAssignmentTarget(accessNode) &&
|
||||
getObjectFlags(objectType) & ObjectFlags.Mapped && getMappedTypeModifiers(objectType as MappedType) & MappedTypeModifiers.IncludeReadonly
|
||||
|
||||
Reference in New Issue
Block a user