diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bbd7def0d784f..4e1698451632c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18545,8 +18545,9 @@ namespace ts { // Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if // one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2, // and Y1 is related to Y2. + const sourceParams = (source as ConditionalType).root.inferTypeParameters; - let sourceExtends = (source).extendsType; + let sourceExtends = instantiateType((source).extendsType, makeFunctionTypeMapper(reportUnmeasurableMarkers)); let mapper: TypeMapper | undefined; if (sourceParams) { // If the source has infer type parameters, we instantiate them in the context of the target diff --git a/tests/baselines/reference/variance.js b/tests/baselines/reference/variance.js index df84404b31beb..e17b9a71194ea 100644 --- a/tests/baselines/reference/variance.js +++ b/tests/baselines/reference/variance.js @@ -24,11 +24,48 @@ class Bar { Bar.instance.push(this); } } + + + +interface Set { + add(value: T): this; +} + +declare const Set: new () => Set; + +// Repro from #31251 (removed getter) + +export abstract class Supervisor { + private static instances_: Set>; + private static instances(): typeof Supervisor.instances_ { + return this.hasOwnProperty('instances_') + ? this.instances_ + : this.instances_ = new Set(); + } + constructor() { + void (this.constructor as typeof Supervisor).instances().add(this); + } + public abstract call(name: N | ('' extends N ? undefined : never), param: P, timeout?: number): Promise; +} + + +// Minimal repro for catching variance probing in then extends type. + +interface A { + x: number extends T ? 1 : 1; +} + +declare let a: A; +declare let b: A<3>; + +a = b; // error +b = a; // error //// [variance.js] "use strict"; // Test cases for parameter variances affected by conditional types. +exports.__esModule = true; var foo = { prop: true }; var x = foo; var y = foo; @@ -43,3 +80,18 @@ var Bar = /** @class */ (function () { }; return Bar; }()); +// Repro from #31251 (removed getter) +var Supervisor = /** @class */ (function () { + function Supervisor() { + void this.constructor.instances().add(this); + } + Supervisor.instances = function () { + return this.hasOwnProperty('instances_') + ? this.instances_ + : this.instances_ = new Set(); + }; + return Supervisor; +}()); +exports.Supervisor = Supervisor; +a = b; // error +b = a; // error diff --git a/tests/baselines/reference/variance.symbols b/tests/baselines/reference/variance.symbols index 0a6ec56d725b6..4d22305f55776 100644 --- a/tests/baselines/reference/variance.symbols +++ b/tests/baselines/reference/variance.symbols @@ -60,3 +60,108 @@ class Bar { } } + + +interface Set { +>Set : Symbol(Set, Decl(variance.ts, 24, 1), Decl(variance.ts, 32, 13)) +>T : Symbol(T, Decl(variance.ts, 28, 14)) + + add(value: T): this; +>add : Symbol(Set.add, Decl(variance.ts, 28, 18)) +>value : Symbol(value, Decl(variance.ts, 29, 8)) +>T : Symbol(T, Decl(variance.ts, 28, 14)) +} + +declare const Set: new () => Set; +>Set : Symbol(Set, Decl(variance.ts, 24, 1), Decl(variance.ts, 32, 13)) +>T : Symbol(T, Decl(variance.ts, 32, 24)) +>Set : Symbol(Set, Decl(variance.ts, 24, 1), Decl(variance.ts, 32, 13)) +>T : Symbol(T, Decl(variance.ts, 32, 24)) + +// Repro from #31251 (removed getter) + +export abstract class Supervisor { +>Supervisor : Symbol(Supervisor, Decl(variance.ts, 32, 39)) +>N : Symbol(N, Decl(variance.ts, 36, 33)) +>P : Symbol(P, Decl(variance.ts, 36, 50)) +>R : Symbol(R, Decl(variance.ts, 36, 63)) + + private static instances_: Set>; +>instances_ : Symbol(Supervisor.instances_, Decl(variance.ts, 36, 78)) +>Set : Symbol(Set, Decl(variance.ts, 24, 1), Decl(variance.ts, 32, 13)) +>Supervisor : Symbol(Supervisor, Decl(variance.ts, 32, 39)) + + private static instances(): typeof Supervisor.instances_ { +>instances : Symbol(Supervisor.instances, Decl(variance.ts, 37, 73)) +>Supervisor.instances_ : Symbol(Supervisor.instances_, Decl(variance.ts, 36, 78)) +>Supervisor : Symbol(Supervisor, Decl(variance.ts, 32, 39)) +>instances_ : Symbol(Supervisor.instances_, Decl(variance.ts, 36, 78)) + + return this.hasOwnProperty('instances_') +>this.hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) +>this : Symbol(Supervisor, Decl(variance.ts, 32, 39)) +>hasOwnProperty : Symbol(Object.hasOwnProperty, Decl(lib.es5.d.ts, --, --)) + + ? this.instances_ +>this.instances_ : Symbol(Supervisor.instances_, Decl(variance.ts, 36, 78)) +>this : Symbol(Supervisor, Decl(variance.ts, 32, 39)) +>instances_ : Symbol(Supervisor.instances_, Decl(variance.ts, 36, 78)) + + : this.instances_ = new Set(); +>this.instances_ : Symbol(Supervisor.instances_, Decl(variance.ts, 36, 78)) +>this : Symbol(Supervisor, Decl(variance.ts, 32, 39)) +>instances_ : Symbol(Supervisor.instances_, Decl(variance.ts, 36, 78)) +>Set : Symbol(Set, Decl(variance.ts, 24, 1), Decl(variance.ts, 32, 13)) + } + constructor() { + void (this.constructor as typeof Supervisor).instances().add(this); +>(this.constructor as typeof Supervisor).instances().add : Symbol(Set.add, Decl(variance.ts, 28, 18)) +>(this.constructor as typeof Supervisor).instances : Symbol(Supervisor.instances, Decl(variance.ts, 37, 73)) +>this.constructor : Symbol(Object.constructor, Decl(lib.es5.d.ts, --, --)) +>this : Symbol(Supervisor, Decl(variance.ts, 32, 39)) +>constructor : Symbol(Object.constructor, Decl(lib.es5.d.ts, --, --)) +>Supervisor : Symbol(Supervisor, Decl(variance.ts, 32, 39)) +>instances : Symbol(Supervisor.instances, Decl(variance.ts, 37, 73)) +>add : Symbol(Set.add, Decl(variance.ts, 28, 18)) +>this : Symbol(Supervisor, Decl(variance.ts, 32, 39)) + } + public abstract call(name: N | ('' extends N ? undefined : never), param: P, timeout?: number): Promise; +>call : Symbol(Supervisor.call, Decl(variance.ts, 45, 5)) +>name : Symbol(name, Decl(variance.ts, 46, 25)) +>N : Symbol(N, Decl(variance.ts, 36, 33)) +>N : Symbol(N, Decl(variance.ts, 36, 33)) +>param : Symbol(param, Decl(variance.ts, 46, 70)) +>P : Symbol(P, Decl(variance.ts, 36, 50)) +>timeout : Symbol(timeout, Decl(variance.ts, 46, 80)) +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) +>R : Symbol(R, Decl(variance.ts, 36, 63)) +} + + +// Minimal repro for catching variance probing in then extends type. + +interface A { +>A : Symbol(A, Decl(variance.ts, 47, 1)) +>T : Symbol(T, Decl(variance.ts, 52, 12)) + + x: number extends T ? 1 : 1; +>x : Symbol(A.x, Decl(variance.ts, 52, 16)) +>T : Symbol(T, Decl(variance.ts, 52, 12)) +} + +declare let a: A; +>a : Symbol(a, Decl(variance.ts, 56, 11)) +>A : Symbol(A, Decl(variance.ts, 47, 1)) + +declare let b: A<3>; +>b : Symbol(b, Decl(variance.ts, 57, 11)) +>A : Symbol(A, Decl(variance.ts, 47, 1)) + +a = b; // error +>a : Symbol(a, Decl(variance.ts, 56, 11)) +>b : Symbol(b, Decl(variance.ts, 57, 11)) + +b = a; // error +>b : Symbol(b, Decl(variance.ts, 57, 11)) +>a : Symbol(a, Decl(variance.ts, 56, 11)) + diff --git a/tests/baselines/reference/variance.types b/tests/baselines/reference/variance.types index 08ee1053b3dba..8c80c8e82255c 100644 --- a/tests/baselines/reference/variance.types +++ b/tests/baselines/reference/variance.types @@ -56,3 +56,97 @@ class Bar { } } + + +interface Set { + add(value: T): this; +>add : (value: T) => this +>value : T +} + +declare const Set: new () => Set; +>Set : new () => Set + +// Repro from #31251 (removed getter) + +export abstract class Supervisor { +>Supervisor : Supervisor + + private static instances_: Set>; +>instances_ : Set> + + private static instances(): typeof Supervisor.instances_ { +>instances : () => Set> +>Supervisor.instances_ : Set> +>Supervisor : typeof Supervisor +>instances_ : Set> + + return this.hasOwnProperty('instances_') +>this.hasOwnProperty('instances_') ? this.instances_ : this.instances_ = new Set() : Set> +>this.hasOwnProperty('instances_') : boolean +>this.hasOwnProperty : (v: string | number | symbol) => boolean +>this : typeof Supervisor +>hasOwnProperty : (v: string | number | symbol) => boolean +>'instances_' : "instances_" + + ? this.instances_ +>this.instances_ : Set> +>this : typeof Supervisor +>instances_ : Set> + + : this.instances_ = new Set(); +>this.instances_ = new Set() : Set> +>this.instances_ : Set> +>this : typeof Supervisor +>instances_ : Set> +>new Set() : Set> +>Set : new () => Set + } + constructor() { + void (this.constructor as typeof Supervisor).instances().add(this); +>void (this.constructor as typeof Supervisor).instances().add(this) : undefined +>(this.constructor as typeof Supervisor).instances().add(this) : Set> +>(this.constructor as typeof Supervisor).instances().add : (value: Supervisor) => Set> +>(this.constructor as typeof Supervisor).instances() : Set> +>(this.constructor as typeof Supervisor).instances : () => Set> +>(this.constructor as typeof Supervisor) : typeof Supervisor +>this.constructor as typeof Supervisor : typeof Supervisor +>this.constructor : Function +>this : this +>constructor : Function +>Supervisor : typeof Supervisor +>instances : () => Set> +>add : (value: Supervisor) => Set> +>this : this + } + public abstract call(name: N | ('' extends N ? undefined : never), param: P, timeout?: number): Promise; +>call : (name: N | ("" extends N ? undefined : never), param: P, timeout?: number | undefined) => Promise +>name : N | ("" extends N ? undefined : never) +>param : P +>timeout : number | undefined +} + + +// Minimal repro for catching variance probing in then extends type. + +interface A { + x: number extends T ? 1 : 1; +>x : number extends T ? 1 : 1 +} + +declare let a: A; +>a : A + +declare let b: A<3>; +>b : A<3> + +a = b; // error +>a = b : A<3> +>a : A +>b : A<3> + +b = a; // error +>b = a : A +>b : A<3> +>a : A + diff --git a/tests/cases/conformance/types/conditional/variance.ts b/tests/cases/conformance/types/conditional/variance.ts index 1dd5db5c67e8f..761c460bef3a6 100644 --- a/tests/cases/conformance/types/conditional/variance.ts +++ b/tests/cases/conformance/types/conditional/variance.ts @@ -25,3 +25,39 @@ class Bar { Bar.instance.push(this); } } + + + +interface Set { + add(value: T): this; +} + +declare const Set: new () => Set; + +// Repro from #31251 (removed getter) + +export abstract class Supervisor { + private static instances_: Set>; + private static instances(): typeof Supervisor.instances_ { + return this.hasOwnProperty('instances_') + ? this.instances_ + : this.instances_ = new Set(); + } + constructor() { + void (this.constructor as typeof Supervisor).instances().add(this); + } + public abstract call(name: N | ('' extends N ? undefined : never), param: P, timeout?: number): Promise; +} + + +// Minimal repro for catching variance probing in then extends type. + +interface A { + x: number extends T ? 1 : 1; +} + +declare let a: A; +declare let b: A<3>; + +a = b; // error +b = a; // error