From 529fc9e259ea03c2d72d0663f33cd613faffde6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 30 Apr 2025 23:48:21 +0200 Subject: [PATCH] Don't obtain apparent type of contextual types being optional type variables --- src/compiler/checker.ts | 2 +- .../inferenceFromGenericClass1.symbols | 81 +++++++++++++++++ .../inferenceFromGenericClass1.types | 91 +++++++++++++++++++ .../compiler/inferenceFromGenericClass1.ts | 32 +++++++ 4 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/inferenceFromGenericClass1.symbols create mode 100644 tests/baselines/reference/inferenceFromGenericClass1.types create mode 100644 tests/cases/compiler/inferenceFromGenericClass1.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index be3965258a516..4a78b0405d657 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -32412,7 +32412,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { getContextualTypeForObjectLiteralMethod(node, contextFlags) : getContextualType(node, contextFlags); const instantiatedType = instantiateContextualType(contextualType, node, contextFlags); - if (instantiatedType && !(contextFlags && contextFlags & ContextFlags.NoConstraints && instantiatedType.flags & TypeFlags.TypeVariable)) { + if (instantiatedType && !(contextFlags && contextFlags & ContextFlags.NoConstraints && maybeTypeOfKind(getNonNullableType(instantiatedType), TypeFlags.TypeVariable))) { const apparentType = mapType( instantiatedType, // When obtaining apparent type of *contextual* type we don't want to get apparent type of mapped types. diff --git a/tests/baselines/reference/inferenceFromGenericClass1.symbols b/tests/baselines/reference/inferenceFromGenericClass1.symbols new file mode 100644 index 0000000000000..e9ddbf7516548 --- /dev/null +++ b/tests/baselines/reference/inferenceFromGenericClass1.symbols @@ -0,0 +1,81 @@ +//// [tests/cases/compiler/inferenceFromGenericClass1.ts] //// + +=== inferenceFromGenericClass1.ts === +// https://github.com/microsoft/TypeScript/issues/61633 + +type AnyConstructor = new (...args: any[]) => object; +>AnyConstructor : Symbol(AnyConstructor, Decl(inferenceFromGenericClass1.ts, 0, 0)) +>args : Symbol(args, Decl(inferenceFromGenericClass1.ts, 2, 27)) + +class Container {} +>Container : Symbol(Container, Decl(inferenceFromGenericClass1.ts, 2, 53)) +>T : Symbol(T, Decl(inferenceFromGenericClass1.ts, 4, 16)) + +declare function RenderFlagsMixin1< +>RenderFlagsMixin1 : Symbol(RenderFlagsMixin1, Decl(inferenceFromGenericClass1.ts, 4, 21)) + + BaseClass extends AnyConstructor | undefined = undefined, +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 6, 35)) +>AnyConstructor : Symbol(AnyConstructor, Decl(inferenceFromGenericClass1.ts, 0, 0)) + +>(Base?: BaseClass): BaseClass; +>Base : Symbol(Base, Decl(inferenceFromGenericClass1.ts, 8, 2)) +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 6, 35)) +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 6, 35)) + +const result1 = RenderFlagsMixin1(Container); +>result1 : Symbol(result1, Decl(inferenceFromGenericClass1.ts, 10, 5)) +>RenderFlagsMixin1 : Symbol(RenderFlagsMixin1, Decl(inferenceFromGenericClass1.ts, 4, 21)) +>Container : Symbol(Container, Decl(inferenceFromGenericClass1.ts, 2, 53)) + +declare function RenderFlagsMixin2< +>RenderFlagsMixin2 : Symbol(RenderFlagsMixin2, Decl(inferenceFromGenericClass1.ts, 10, 45)) + + BaseClass extends AnyConstructor | undefined = undefined, +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 12, 35)) +>AnyConstructor : Symbol(AnyConstructor, Decl(inferenceFromGenericClass1.ts, 0, 0)) + +>(Base: BaseClass): BaseClass; +>Base : Symbol(Base, Decl(inferenceFromGenericClass1.ts, 14, 2)) +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 12, 35)) +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 12, 35)) + +const result2 = RenderFlagsMixin2(Container); +>result2 : Symbol(result2, Decl(inferenceFromGenericClass1.ts, 16, 5)) +>RenderFlagsMixin2 : Symbol(RenderFlagsMixin2, Decl(inferenceFromGenericClass1.ts, 10, 45)) +>Container : Symbol(Container, Decl(inferenceFromGenericClass1.ts, 2, 53)) + +declare function RenderFlagsMixin3< +>RenderFlagsMixin3 : Symbol(RenderFlagsMixin3, Decl(inferenceFromGenericClass1.ts, 16, 45)) + + BaseClass extends AnyConstructor | undefined = undefined, +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 18, 35)) +>AnyConstructor : Symbol(AnyConstructor, Decl(inferenceFromGenericClass1.ts, 0, 0)) + +>(Base: BaseClass | number): BaseClass; +>Base : Symbol(Base, Decl(inferenceFromGenericClass1.ts, 20, 2)) +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 18, 35)) +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 18, 35)) + +const result3 = RenderFlagsMixin3(Container); +>result3 : Symbol(result3, Decl(inferenceFromGenericClass1.ts, 22, 5)) +>RenderFlagsMixin3 : Symbol(RenderFlagsMixin3, Decl(inferenceFromGenericClass1.ts, 16, 45)) +>Container : Symbol(Container, Decl(inferenceFromGenericClass1.ts, 2, 53)) + +declare function RenderFlagsMixin4< +>RenderFlagsMixin4 : Symbol(RenderFlagsMixin4, Decl(inferenceFromGenericClass1.ts, 22, 45)) + + BaseClass extends AnyConstructor | undefined = undefined, +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 24, 35)) +>AnyConstructor : Symbol(AnyConstructor, Decl(inferenceFromGenericClass1.ts, 0, 0)) + +>(Base?: BaseClass | number): BaseClass; +>Base : Symbol(Base, Decl(inferenceFromGenericClass1.ts, 26, 2)) +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 24, 35)) +>BaseClass : Symbol(BaseClass, Decl(inferenceFromGenericClass1.ts, 24, 35)) + +const result4 = RenderFlagsMixin4(Container); +>result4 : Symbol(result4, Decl(inferenceFromGenericClass1.ts, 28, 5)) +>RenderFlagsMixin4 : Symbol(RenderFlagsMixin4, Decl(inferenceFromGenericClass1.ts, 22, 45)) +>Container : Symbol(Container, Decl(inferenceFromGenericClass1.ts, 2, 53)) + diff --git a/tests/baselines/reference/inferenceFromGenericClass1.types b/tests/baselines/reference/inferenceFromGenericClass1.types new file mode 100644 index 0000000000000..3dc8570735248 --- /dev/null +++ b/tests/baselines/reference/inferenceFromGenericClass1.types @@ -0,0 +1,91 @@ +//// [tests/cases/compiler/inferenceFromGenericClass1.ts] //// + +=== inferenceFromGenericClass1.ts === +// https://github.com/microsoft/TypeScript/issues/61633 + +type AnyConstructor = new (...args: any[]) => object; +>AnyConstructor : AnyConstructor +> : ^^^^^^^^^^^^^^ +>args : any[] +> : ^^^^^ + +class Container {} +>Container : Container +> : ^^^^^^^^^^^^ + +declare function RenderFlagsMixin1< +>RenderFlagsMixin1 : (Base?: BaseClass) => BaseClass +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^ ^^^^^ + + BaseClass extends AnyConstructor | undefined = undefined, +>(Base?: BaseClass): BaseClass; +>Base : BaseClass | undefined +> : ^^^^^^^^^^^^^^^^^^^^^ + +const result1 = RenderFlagsMixin1(Container); +>result1 : typeof Container +> : ^^^^^^^^^^^^^^^^ +>RenderFlagsMixin1(Container) : typeof Container +> : ^^^^^^^^^^^^^^^^ +>RenderFlagsMixin1 : (Base?: BaseClass) => BaseClass +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^ ^^^^^ +>Container : typeof Container +> : ^^^^^^^^^^^^^^^^ + +declare function RenderFlagsMixin2< +>RenderFlagsMixin2 : (Base: BaseClass) => BaseClass +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^ ^^^^^ + + BaseClass extends AnyConstructor | undefined = undefined, +>(Base: BaseClass): BaseClass; +>Base : BaseClass +> : ^^^^^^^^^ + +const result2 = RenderFlagsMixin2(Container); +>result2 : typeof Container +> : ^^^^^^^^^^^^^^^^ +>RenderFlagsMixin2(Container) : typeof Container +> : ^^^^^^^^^^^^^^^^ +>RenderFlagsMixin2 : (Base: BaseClass) => BaseClass +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^ ^^^^^ +>Container : typeof Container +> : ^^^^^^^^^^^^^^^^ + +declare function RenderFlagsMixin3< +>RenderFlagsMixin3 : (Base: BaseClass | number) => BaseClass +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^ ^^^^^ + + BaseClass extends AnyConstructor | undefined = undefined, +>(Base: BaseClass | number): BaseClass; +>Base : number | BaseClass +> : ^^^^^^^^^^^^^^^^^^ + +const result3 = RenderFlagsMixin3(Container); +>result3 : typeof Container +> : ^^^^^^^^^^^^^^^^ +>RenderFlagsMixin3(Container) : typeof Container +> : ^^^^^^^^^^^^^^^^ +>RenderFlagsMixin3 : (Base: BaseClass | number) => BaseClass +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^ ^^^^^ +>Container : typeof Container +> : ^^^^^^^^^^^^^^^^ + +declare function RenderFlagsMixin4< +>RenderFlagsMixin4 : (Base?: BaseClass | number) => BaseClass +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^ ^^^^^ + + BaseClass extends AnyConstructor | undefined = undefined, +>(Base?: BaseClass | number): BaseClass; +>Base : number | BaseClass | undefined +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +const result4 = RenderFlagsMixin4(Container); +>result4 : typeof Container +> : ^^^^^^^^^^^^^^^^ +>RenderFlagsMixin4(Container) : typeof Container +> : ^^^^^^^^^^^^^^^^ +>RenderFlagsMixin4 : (Base?: BaseClass | number) => BaseClass +> : ^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^ ^^^^^ +>Container : typeof Container +> : ^^^^^^^^^^^^^^^^ + diff --git a/tests/cases/compiler/inferenceFromGenericClass1.ts b/tests/cases/compiler/inferenceFromGenericClass1.ts new file mode 100644 index 0000000000000..0a4f087bbdac8 --- /dev/null +++ b/tests/cases/compiler/inferenceFromGenericClass1.ts @@ -0,0 +1,32 @@ +// @strict: true +// @noEmit: true + +// https://github.com/microsoft/TypeScript/issues/61633 + +type AnyConstructor = new (...args: any[]) => object; + +class Container {} + +declare function RenderFlagsMixin1< + BaseClass extends AnyConstructor | undefined = undefined, +>(Base?: BaseClass): BaseClass; + +const result1 = RenderFlagsMixin1(Container); + +declare function RenderFlagsMixin2< + BaseClass extends AnyConstructor | undefined = undefined, +>(Base: BaseClass): BaseClass; + +const result2 = RenderFlagsMixin2(Container); + +declare function RenderFlagsMixin3< + BaseClass extends AnyConstructor | undefined = undefined, +>(Base: BaseClass | number): BaseClass; + +const result3 = RenderFlagsMixin3(Container); + +declare function RenderFlagsMixin4< + BaseClass extends AnyConstructor | undefined = undefined, +>(Base?: BaseClass | number): BaseClass; + +const result4 = RenderFlagsMixin4(Container);