From 4aa8c2fbcb1e4e0d861094f3001fe6093c7a805c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 12 Apr 2024 09:39:44 -0700 Subject: [PATCH 1/2] Use better context scope for class constructor implementation signatures --- src/compiler/checker.ts | 3 +- ...tIncorrectlyInstantiatedWithInnerResult.js | 55 ++++++++++++ ...rrectlyInstantiatedWithInnerResult.symbols | 87 +++++++++++++++++++ ...correctlyInstantiatedWithInnerResult.types | 77 ++++++++++++++++ ...tIncorrectlyInstantiatedWithInnerResult.ts | 24 +++++ 5 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js create mode 100644 tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols create mode 100644 tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types create mode 100644 tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b7281687ad710..782826e568f3f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34806,7 +34806,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (candidate.typeParameters) { // If we are *inside the body of candidate*, we need to create a clone of `candidate` with differing type parameter identities, // so our inference results for this call doesn't pollute expression types referencing the outer type parameter! - if (candidate.declaration && findAncestor(node, a => a === candidate.declaration)) { + const candidateParameterContext = candidate.declaration && isConstructorDeclaration(candidate.declaration) ? candidate.declaration.parent : candidate.declaration; + if (candidateParameterContext && findAncestor(node, a => a === candidateParameterContext)) { candidate = getImplementationSignature(candidate); } let typeArgumentTypes: readonly Type[] | undefined; diff --git a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js new file mode 100644 index 0000000000000..7a30832eee67d --- /dev/null +++ b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js @@ -0,0 +1,55 @@ +//// [tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts] //// + +//// [inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts] +// simple example +export class Test { + constructor(public a: A, public b: B) { } + + test(c: C): Test { + return new Test(this.b, c); + } +} + +// complicated one +interface Supervisor { + zip(right: Supervisor): Supervisor<[T, A]>; +} + +export class Zip implements Supervisor { + constructor( + readonly left: Supervisor, + readonly right: Supervisor, + ) { } + + zip(right: Supervisor): Supervisor<[[T0, T1], A]> { + return new Zip(this, right); + } +} + +//// [inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Zip = exports.Test = void 0; +// simple example +var Test = /** @class */ (function () { + function Test(a, b) { + this.a = a; + this.b = b; + } + Test.prototype.test = function (c) { + return new Test(this.b, c); + }; + return Test; +}()); +exports.Test = Test; +var Zip = /** @class */ (function () { + function Zip(left, right) { + this.left = left; + this.right = right; + } + Zip.prototype.zip = function (right) { + return new Zip(this, right); + }; + return Zip; +}()); +exports.Zip = Zip; diff --git a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols new file mode 100644 index 0000000000000..c1eff2c0a83f2 --- /dev/null +++ b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols @@ -0,0 +1,87 @@ +//// [tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts] //// + +=== inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts === +// simple example +export class Test { +>Test : Symbol(Test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 0, 0)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 18)) +>B : Symbol(B, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 20)) + + constructor(public a: A, public b: B) { } +>a : Symbol(Test.a, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 16)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 18)) +>b : Symbol(Test.b, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 28)) +>B : Symbol(B, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 20)) + + test(c: C): Test { +>test : Symbol(Test.test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 45)) +>C : Symbol(C, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 9)) +>c : Symbol(c, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 12)) +>C : Symbol(C, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 9)) +>Test : Symbol(Test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 0, 0)) +>B : Symbol(B, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 1, 20)) +>C : Symbol(C, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 9)) + + return new Test(this.b, c); +>Test : Symbol(Test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 0, 0)) +>this.b : Symbol(Test.b, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 28)) +>this : Symbol(Test, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 0, 0)) +>b : Symbol(Test.b, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 2, 28)) +>c : Symbol(c, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 4, 12)) + } +} + +// complicated one +interface Supervisor { +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 10, 21)) + + zip(right: Supervisor): Supervisor<[T, A]>; +>zip : Symbol(Supervisor.zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 10, 29)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 11, 8)) +>right : Symbol(right, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 11, 11)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 11, 8)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 10, 21)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 11, 8)) +} + +export class Zip implements Supervisor { +>Zip : Symbol(Zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 12, 1)) +>T0 : Symbol(T0, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 17)) +>T1 : Symbol(T1, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 24)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T0 : Symbol(T0, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 17)) +>T1 : Symbol(T1, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 24)) + + constructor( + readonly left: Supervisor, +>left : Symbol(Zip.left, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 15, 16)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T0 : Symbol(T0, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 17)) + + readonly right: Supervisor, +>right : Symbol(Zip.right, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 16, 38)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T1 : Symbol(T1, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 24)) + + ) { } + + zip(right: Supervisor): Supervisor<[[T0, T1], A]> { +>zip : Symbol(Zip.zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 18, 9)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 8)) +>right : Symbol(right, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 11)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 8)) +>Supervisor : Symbol(Supervisor, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 7, 1)) +>T0 : Symbol(T0, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 17)) +>T1 : Symbol(T1, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 14, 24)) +>A : Symbol(A, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 8)) + + return new Zip(this, right); +>Zip : Symbol(Zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 12, 1)) +>this : Symbol(Zip, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 12, 1)) +>right : Symbol(right, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 11)) + } +} diff --git a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types new file mode 100644 index 0000000000000..345342648ad7e --- /dev/null +++ b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types @@ -0,0 +1,77 @@ +//// [tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts] //// + +=== inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts === +// simple example +export class Test { +>Test : Test +> : ^^^^^^^^^^ + + constructor(public a: A, public b: B) { } +>a : A +> : ^ +>b : B +> : ^ + + test(c: C): Test { +>test : (c: C) => Test +> : ^ ^^ ^^ ^^^^^ +>c : C +> : ^ + + return new Test(this.b, c); +>new Test(this.b, c) : Test +> : ^^^^^^^^^^ +>Test : typeof Test +> : ^^^^^^^^^^^ +>this.b : B +> : ^ +>this : this +> : ^^^^ +>b : B +> : ^ +>c : C +> : ^ + } +} + +// complicated one +interface Supervisor { + zip(right: Supervisor): Supervisor<[T, A]>; +>zip : (right: Supervisor) => Supervisor<[T, A]> +> : ^ ^^ ^^ ^^^^^ +>right : Supervisor +> : ^^^^^^^^^^^^^ +} + +export class Zip implements Supervisor { +>Zip : Zip +> : ^^^^^^^^^^^ + + constructor( + readonly left: Supervisor, +>left : Supervisor +> : ^^^^^^^^^^^^^^ + + readonly right: Supervisor, +>right : Supervisor +> : ^^^^^^^^^^^^^^ + + ) { } + + zip(right: Supervisor): Supervisor<[[T0, T1], A]> { +>zip : (right: Supervisor) => Supervisor<[[T0, T1], A]> +> : ^ ^^ ^^ ^^^^^ +>right : Supervisor +> : ^^^^^^^^^^^^^ + + return new Zip(this, right); +>new Zip(this, right) : Zip<[T0, T1], A> +> : ^^^^^^^^^^^^^^^^ +>Zip : typeof Zip +> : ^^^^^^^^^^ +>this : this +> : ^^^^ +>right : Supervisor +> : ^^^^^^^^^^^^^ + } +} diff --git a/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts b/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts new file mode 100644 index 0000000000000..ae0ec6b0901a9 --- /dev/null +++ b/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts @@ -0,0 +1,24 @@ +// simple example +export class Test { + constructor(public a: A, public b: B) { } + + test(c: C): Test { + return new Test(this.b, c); + } +} + +// complicated one +interface Supervisor { + zip(right: Supervisor): Supervisor<[T, A]>; +} + +export class Zip implements Supervisor { + constructor( + readonly left: Supervisor, + readonly right: Supervisor, + ) { } + + zip(right: Supervisor): Supervisor<[[T0, T1], A]> { + return new Zip(this, right); + } +} \ No newline at end of file From 92f45436ce5d38c1db84c957a5e15b0e0edfec87 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 12 Apr 2024 10:51:21 -0700 Subject: [PATCH 2/2] Prefer using the type parameter location itself, if available --- src/compiler/checker.ts | 3 +- ...tIncorrectlyInstantiatedWithInnerResult.js | 52 +++++++++++----- ...rrectlyInstantiatedWithInnerResult.symbols | 51 +++++++++++++++ ...correctlyInstantiatedWithInnerResult.types | 62 +++++++++++++++++++ ...tIncorrectlyInstantiatedWithInnerResult.ts | 15 +++++ 5 files changed, 165 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 782826e568f3f..612abd197517a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34806,7 +34806,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (candidate.typeParameters) { // If we are *inside the body of candidate*, we need to create a clone of `candidate` with differing type parameter identities, // so our inference results for this call doesn't pollute expression types referencing the outer type parameter! - const candidateParameterContext = candidate.declaration && isConstructorDeclaration(candidate.declaration) ? candidate.declaration.parent : candidate.declaration; + const paramLocation = candidate.typeParameters[0].symbol.declarations?.[0]?.parent; + const candidateParameterContext = paramLocation || (candidate.declaration && isConstructorDeclaration(candidate.declaration) ? candidate.declaration.parent : candidate.declaration); if (candidateParameterContext && findAncestor(node, a => a === candidateParameterContext)) { candidate = getImplementationSignature(candidate); } diff --git a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js index 7a30832eee67d..e407a66f3f087 100644 --- a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js +++ b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js @@ -24,32 +24,50 @@ export class Zip implements Supervisor { zip(right: Supervisor): Supervisor<[[T0, T1], A]> { return new Zip(this, right); } +} + +// indirect +type Assign = Omit & U; + +class Base { + constructor(public t: T) { } +} + +export class Foo extends Base { + update(): Foo> { + const v: Assign = Object.assign(this.t, { x: 1 }); + return new Foo(v); + } } //// [inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.js] -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Zip = exports.Test = void 0; // simple example -var Test = /** @class */ (function () { - function Test(a, b) { +export class Test { + constructor(a, b) { this.a = a; this.b = b; } - Test.prototype.test = function (c) { + test(c) { return new Test(this.b, c); - }; - return Test; -}()); -exports.Test = Test; -var Zip = /** @class */ (function () { - function Zip(left, right) { + } +} +export class Zip { + constructor(left, right) { this.left = left; this.right = right; } - Zip.prototype.zip = function (right) { + zip(right) { return new Zip(this, right); - }; - return Zip; -}()); -exports.Zip = Zip; + } +} +class Base { + constructor(t) { + this.t = t; + } +} +export class Foo extends Base { + update() { + const v = Object.assign(this.t, { x: 1 }); + return new Foo(v); + } +} diff --git a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols index c1eff2c0a83f2..5eff036d33422 100644 --- a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols +++ b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.symbols @@ -85,3 +85,54 @@ export class Zip implements Supervisor { >right : Symbol(right, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 20, 11)) } } + +// indirect +type Assign = Omit & U; +>Assign : Symbol(Assign, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 23, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 12)) +>U : Symbol(U, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 14)) +>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 12)) +>U : Symbol(U, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 14)) +>U : Symbol(U, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 14)) + +class Base { +>Base : Symbol(Base, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 41)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 28, 11)) + + constructor(public t: T) { } +>t : Symbol(Base.t, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 29, 16)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 28, 11)) +} + +export class Foo extends Base { +>Foo : Symbol(Foo, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 30, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 17)) +>Base : Symbol(Base, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 26, 41)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 17)) + + update(): Foo> { +>update : Symbol(Foo.update, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 37)) +>Foo : Symbol(Foo, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 30, 1)) +>Assign : Symbol(Assign, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 23, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 17)) +>x : Symbol(x, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 33, 29)) + + const v: Assign = Object.assign(this.t, { x: 1 }); +>v : Symbol(v, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 34, 13)) +>Assign : Symbol(Assign, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 23, 1)) +>T : Symbol(T, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 32, 17)) +>x : Symbol(x, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 34, 28)) +>Object.assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>Object : Symbol(Object, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>assign : Symbol(ObjectConstructor.assign, Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --)) +>this.t : Symbol(Base.t, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 29, 16)) +>this : Symbol(Foo, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 30, 1)) +>t : Symbol(Base.t, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 29, 16)) +>x : Symbol(x, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 34, 67)) + + return new Foo(v); +>Foo : Symbol(Foo, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 30, 1)) +>v : Symbol(v, Decl(inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts, 34, 13)) + } +} diff --git a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types index 345342648ad7e..fd159c4a51979 100644 --- a/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types +++ b/tests/baselines/reference/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.types @@ -75,3 +75,65 @@ export class Zip implements Supervisor { > : ^^^^^^^^^^^^^ } } + +// indirect +type Assign = Omit & U; +>Assign : Assign +> : ^^^^^^^^^^^^ + +class Base { +>Base : Base +> : ^^^^^^^ + + constructor(public t: T) { } +>t : T +> : ^ +} + +export class Foo extends Base { +>Foo : Foo +> : ^^^^^^ +>Base : Base +> : ^^^^^^^ + + update(): Foo> { +>update : () => Foo> +> : ^^^^^^ +>x : number +> : ^^^^^^ + + const v: Assign = Object.assign(this.t, { x: 1 }); +>v : Assign +> : ^^^^^^^^^^^^^^^ ^^^^ +>x : number +> : ^^^^^^ +>Object.assign(this.t, { x: 1 }) : T & { x: number; } +> : ^^^^^^^^^^^^^^^^^^ +>Object.assign : { (target: T_1, source: U): T_1 & U; (target: T_2, source1: U_1, source2: V): T_2 & U_1 & V; (target: T_3, source1: U_2, source2: V_1, source3: W): T_3 & U_2 & V_1 & W; (target: object, ...sources: any[]): any; } +> : ^^^ ^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^ ^^^^^^^^^ +>Object : ObjectConstructor +> : ^^^^^^^^^^^^^^^^^ +>assign : { (target: T_1, source: U): T_1 & U; (target: T_2, source1: U_1, source2: V): T_2 & U_1 & V; (target: T_3, source1: U_2, source2: V_1, source3: W): T_3 & U_2 & V_1 & W; (target: object, ...sources: any[]): any; } +> : ^^^ ^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ ^^^^^ ^^ ^^^^^^^^^ +>this.t : T +> : ^ +>this : this +> : ^^^^ +>t : T +> : ^ +>{ x: 1 } : { x: number; } +> : ^^^^^^^^^^^^^^ +>x : number +> : ^^^^^^ +>1 : 1 +> : ^ + + return new Foo(v); +>new Foo(v) : Foo> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>Foo : typeof Foo +> : ^^^^^^^^^^ +>v : Assign +> : ^^^^^^^^^^^^^^^^^^^^^^^^^ + } +} diff --git a/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts b/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts index ae0ec6b0901a9..f35f4bf0d4610 100644 --- a/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts +++ b/tests/cases/compiler/inferenceOuterResultNotIncorrectlyInstantiatedWithInnerResult.ts @@ -1,3 +1,4 @@ +// @target: es6 // simple example export class Test { constructor(public a: A, public b: B) { } @@ -21,4 +22,18 @@ export class Zip implements Supervisor { zip(right: Supervisor): Supervisor<[[T0, T1], A]> { return new Zip(this, right); } +} + +// indirect +type Assign = Omit & U; + +class Base { + constructor(public t: T) { } +} + +export class Foo extends Base { + update(): Foo> { + const v: Assign = Object.assign(this.t, { x: 1 }); + return new Foo(v); + } } \ No newline at end of file