diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 54788091d6b75..44d6ca66853a6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12498,11 +12498,25 @@ namespace ts { } function isGenericObjectType(type: Type): boolean { - return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.GenericMappedType); + if (type.flags & TypeFlags.UnionOrIntersection) { + if (!((type).objectFlags & ObjectFlags.IsGenericObjectTypeComputed)) { + (type).objectFlags |= ObjectFlags.IsGenericObjectTypeComputed | + (some((type).types, isGenericObjectType) ? ObjectFlags.IsGenericObjectType : 0); + } + return !!((type).objectFlags & ObjectFlags.IsGenericObjectType); + } + return !!(type.flags & TypeFlags.InstantiableNonPrimitive) || isGenericMappedType(type); } function isGenericIndexType(type: Type): boolean { - return maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive | TypeFlags.Index); + if (type.flags & TypeFlags.UnionOrIntersection) { + if (!((type).objectFlags & ObjectFlags.IsGenericIndexTypeComputed)) { + (type).objectFlags |= ObjectFlags.IsGenericIndexTypeComputed | + (some((type).types, isGenericIndexType) ? ObjectFlags.IsGenericIndexType : 0); + } + return !!((type).objectFlags & ObjectFlags.IsGenericIndexType); + } + return !!(type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index)); } function isThisTypeParameter(type: Type): boolean { @@ -12726,7 +12740,7 @@ namespace ts { if (checkType === wildcardType || extendsType === wildcardType) { return wildcardType; } - const checkTypeInstantiable = maybeTypeOfKind(checkType, TypeFlags.Instantiable | TypeFlags.GenericMappedType); + const checkTypeInstantiable = isGenericObjectType(checkType) || isGenericIndexType(checkType); let combinedMapper: TypeMapper | undefined; if (root.inferTypeParameters) { const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None); @@ -12745,7 +12759,7 @@ namespace ts { // Instantiate the extends type including inferences for 'infer T' type parameters const inferredExtendsType = combinedMapper ? instantiateType(root.extendsType, combinedMapper) : extendsType; // We attempt to resolve the conditional type only when the check and extends types are non-generic - if (!checkTypeInstantiable && !maybeTypeOfKind(inferredExtendsType, TypeFlags.Instantiable | TypeFlags.GenericMappedType)) { + if (!checkTypeInstantiable && !isGenericObjectType(inferredExtendsType) && !isGenericIndexType(inferredExtendsType)) { if (inferredExtendsType.flags & TypeFlags.AnyOrUnknown) { return instantiateType(root.trueType, combinedMapper || mapper); } @@ -27037,7 +27051,7 @@ namespace ts { // Return true if type might be of the given kind. A union or intersection type might be of a given // kind if at least one constituent type is of the given kind. function maybeTypeOfKind(type: Type, kind: TypeFlags): boolean { - if (type.flags & kind & ~TypeFlags.GenericMappedType || kind & TypeFlags.GenericMappedType && isGenericMappedType(type)) { + if (type.flags & kind) { return true; } if (type.flags & TypeFlags.UnionOrIntersection) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c6c499b3cf8d1..32a36306a17d5 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4348,9 +4348,6 @@ namespace ts { IncludesWildcard = Index, /* @internal */ IncludesEmptyObject = IndexedAccess, - // The following flag is used for different purposes by maybeTypeOfKind - /* @internal */ - GenericMappedType = Never, } export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; @@ -4454,6 +4451,14 @@ namespace ts { ContainsObjectOrArrayLiteral = 1 << 20, // Type is or contains object literal type /* @internal */ NonInferrableType = 1 << 21, // Type is or contains anyFunctionType or silentNeverType + /* @internal */ + IsGenericObjectTypeComputed = 1 << 22, // IsGenericObjectType flag has been computed + /* @internal */ + IsGenericObjectType = 1 << 23, // Union or intersection contains generic object type + /* @internal */ + IsGenericIndexTypeComputed = 1 << 24, // IsGenericIndexType flag has been computed + /* @internal */ + IsGenericIndexType = 1 << 25, // Union or intersection contains generic index type ClassOrInterface = Class | Interface, /* @internal */ RequiresWidening = ContainsWideningType | ContainsObjectOrArrayLiteral,