mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 12:51:30 -05:00
Don't reduce 'keyof M' for mapped types with non-distributive 'as' clauses (#41186)
* Don't reduce 'keyof M' for mapped types with non-distributive as clauses * Add regression test * Accept new baselines
This commit is contained in:
@@ -13475,6 +13475,19 @@ namespace ts {
|
||||
constraint;
|
||||
}
|
||||
|
||||
// Ordinarily we reduce a keyof M where M is a mapped type { [P in K as N<P>]: X } to simply N<K>. This however presumes
|
||||
// that N distributes over union types, i.e. that N<A | B | C> is equivalent to N<A> | N<B> | N<C>. That presumption is
|
||||
// generally true, except when N is a non-distributive conditional type or an instantiable type with non-distributive
|
||||
// conditional type as a constituent. In those cases, we cannot reduce keyof M and need to preserve it as is.
|
||||
function isNonDistributiveNameType(type: Type | undefined): boolean {
|
||||
return !!(type && (
|
||||
type.flags & TypeFlags.Conditional && !(<ConditionalType>type).root.isDistributive ||
|
||||
type.flags & (TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral) && some((<UnionOrIntersectionType | TemplateLiteralType>type).types, isNonDistributiveNameType) ||
|
||||
type.flags & (TypeFlags.Index | TypeFlags.StringMapping) && isNonDistributiveNameType((<IndexType | StringMappingType>type).type) ||
|
||||
type.flags & TypeFlags.IndexedAccess && isNonDistributiveNameType((<IndexedAccessType>type).indexType) ||
|
||||
type.flags & TypeFlags.Substitution && isNonDistributiveNameType((<SubstitutionType>type).substitute)));
|
||||
}
|
||||
|
||||
function getLiteralTypeFromPropertyName(name: PropertyName) {
|
||||
if (isPrivateIdentifier(name)) {
|
||||
return neverType;
|
||||
@@ -13522,7 +13535,7 @@ namespace ts {
|
||||
type = getReducedType(type);
|
||||
return type.flags & TypeFlags.Union ? getIntersectionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
|
||||
type.flags & TypeFlags.Intersection ? getUnionType(map((<IntersectionType>type).types, t => getIndexType(t, stringsOnly, noIndexSignatures))) :
|
||||
type.flags & TypeFlags.InstantiableNonPrimitive || isGenericTupleType(type) ? getIndexTypeForGenericType(<InstantiableType | UnionOrIntersectionType>type, stringsOnly) :
|
||||
type.flags & TypeFlags.InstantiableNonPrimitive || isGenericTupleType(type) || isGenericMappedType(type) && isNonDistributiveNameType(getNameTypeFromMappedType(type)) ? getIndexTypeForGenericType(<InstantiableType | UnionOrIntersectionType>type, stringsOnly) :
|
||||
getObjectFlags(type) & ObjectFlags.Mapped ? getIndexTypeForMappedType(<MappedType>type, noIndexSignatures) :
|
||||
type === wildcardType ? wildcardType :
|
||||
type.flags & TypeFlags.Unknown ? neverType :
|
||||
|
||||
Reference in New Issue
Block a user