Compute dervied generic-ness for substitutions and create lower priority inferences for substitutes (#43765)

This commit is contained in:
Wesley Wigham
2021-04-23 15:51:05 -07:00
committed by GitHub
parent bd7d0f26b2
commit dee4903f45
8 changed files with 84 additions and 30 deletions

View File

@@ -14720,6 +14720,13 @@ namespace ts {
}
return !!((<UnionOrIntersectionType>type).objectFlags & ObjectFlags.IsGenericObjectType);
}
if (type.flags & TypeFlags.Substitution) {
if (!((<SubstitutionType>type).objectFlags & ObjectFlags.IsGenericObjectTypeComputed)) {
(<SubstitutionType>type).objectFlags |= ObjectFlags.IsGenericObjectTypeComputed |
(isGenericObjectType((<SubstitutionType>type).substitute) || isGenericObjectType((<SubstitutionType>type).baseType) ? ObjectFlags.IsGenericObjectType : 0);
}
return !!((<SubstitutionType>type).objectFlags & ObjectFlags.IsGenericObjectType);
}
return !!(type.flags & TypeFlags.InstantiableNonPrimitive) || isGenericMappedType(type) || isGenericTupleType(type);
}
@@ -14731,6 +14738,13 @@ namespace ts {
}
return !!((<UnionOrIntersectionType>type).objectFlags & ObjectFlags.IsGenericIndexType);
}
if (type.flags & TypeFlags.Substitution) {
if (!((<SubstitutionType>type).objectFlags & ObjectFlags.IsGenericIndexTypeComputed)) {
(<SubstitutionType>type).objectFlags |= ObjectFlags.IsGenericIndexTypeComputed |
(isGenericIndexType((<SubstitutionType>type).substitute) || isGenericIndexType((<SubstitutionType>type).baseType) ? ObjectFlags.IsGenericIndexType : 0);
}
return !!((<SubstitutionType>type).objectFlags & ObjectFlags.IsGenericIndexType);
}
return !!(type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping)) && !isPatternLiteralType(type);
}
@@ -21128,6 +21142,13 @@ namespace ts {
inferFromTypes((<StringMappingType>source).type, (<StringMappingType>target).type);
}
}
else if (source.flags & TypeFlags.Substitution) {
inferFromTypes((source as SubstitutionType).baseType, target);
const oldPriority = priority;
priority |= InferencePriority.SubstituteSource;
inferFromTypes((source as SubstitutionType).substitute, target); // Make substitute inference at a lower priority
priority = oldPriority;
}
else if (target.flags & TypeFlags.Conditional) {
invokeOnce(source, target, inferToConditionalType);
}

View File

@@ -5201,7 +5201,7 @@ namespace ts {
/* @internal */
IsClassInstanceClone = 1 << 24, // Type is a clone of a class instance type
// Flags that require TypeFlags.UnionOrIntersection
// Flags that require TypeFlags.UnionOrIntersection or TypeFlags.Substitution
/* @internal */
IsGenericObjectTypeComputed = 1 << 22, // IsGenericObjectType flag has been computed
/* @internal */
@@ -5553,6 +5553,7 @@ namespace ts {
// Thus, if Foo has a 'string' constraint on its type parameter, T will satisfy it. Substitution
// types disappear upon instantiation (just like type parameters).
export interface SubstitutionType extends InstantiableType {
objectFlags: ObjectFlags;
baseType: Type; // Target type
substitute: Type; // Type to substitute for type parameter
}
@@ -5663,15 +5664,16 @@ namespace ts {
export const enum InferencePriority {
NakedTypeVariable = 1 << 0, // Naked type variable in union or intersection type
SpeculativeTuple = 1 << 1, // Speculative tuple inference
HomomorphicMappedType = 1 << 2, // Reverse inference for homomorphic mapped type
PartialHomomorphicMappedType = 1 << 3, // Partial reverse inference for homomorphic mapped type
MappedTypeConstraint = 1 << 4, // Reverse inference for mapped type
ContravariantConditional = 1 << 5, // Conditional type in contravariant position
ReturnType = 1 << 6, // Inference made from return type of generic function
LiteralKeyof = 1 << 7, // Inference made from a string literal to a keyof T
NoConstraints = 1 << 8, // Don't infer from constraints of instantiable types
AlwaysStrict = 1 << 9, // Always use strict rules for contravariant inferences
MaxValue = 1 << 10, // Seed for inference priority tracking
SubstituteSource = 1 << 2, // Source of inference originated within a substitution type's substitute
HomomorphicMappedType = 1 << 3, // Reverse inference for homomorphic mapped type
PartialHomomorphicMappedType = 1 << 4, // Partial reverse inference for homomorphic mapped type
MappedTypeConstraint = 1 << 5, // Reverse inference for mapped type
ContravariantConditional = 1 << 6, // Conditional type in contravariant position
ReturnType = 1 << 7, // Inference made from return type of generic function
LiteralKeyof = 1 << 8, // Inference made from a string literal to a keyof T
NoConstraints = 1 << 9, // Don't infer from constraints of instantiable types
AlwaysStrict = 1 << 10, // Always use strict rules for contravariant inferences
MaxValue = 1 << 11, // Seed for inference priority tracking
PriorityImpliesCombination = ReturnType | MappedTypeConstraint | LiteralKeyof, // These priorities imply that the resulting type should be a combination of all candidates
Circularity = -1, // Inference circularity (value less than all other priorities)