diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 65807b5347b86..10b6aaf14f3d0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10200,8 +10200,11 @@ namespace ts { } else if (source.flags & TypeFlags.Conditional) { if (target.flags & TypeFlags.Conditional) { - if (isTypeIdenticalTo((source).checkType, (target).checkType) && - isTypeIdenticalTo((source).extendsType, (target).extendsType)) { + // 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. + if (isTypeIdenticalTo((source).extendsType, (target).extendsType) && + (isRelatedTo((source).checkType, (target).checkType) || isRelatedTo((target).checkType, (source).checkType))) { if (result = isRelatedTo(getTrueTypeFromConditionalType(source), getTrueTypeFromConditionalType(target), reportErrors)) { result &= isRelatedTo(getFalseTypeFromConditionalType(source), getFalseTypeFromConditionalType(target), reportErrors); } diff --git a/tests/baselines/reference/conditionalTypes2.errors.txt b/tests/baselines/reference/conditionalTypes2.errors.txt new file mode 100644 index 0000000000000..a41522102682f --- /dev/null +++ b/tests/baselines/reference/conditionalTypes2.errors.txt @@ -0,0 +1,90 @@ +tests/cases/conformance/types/conditional/conditionalTypes2.ts(15,5): error TS2322: Type 'Covariant' is not assignable to type 'Covariant'. + Type 'A' is not assignable to type 'B'. +tests/cases/conformance/types/conditional/conditionalTypes2.ts(19,5): error TS2322: Type 'Contravariant' is not assignable to type 'Contravariant'. + Type 'A' is not assignable to type 'B'. +tests/cases/conformance/types/conditional/conditionalTypes2.ts(24,5): error TS2322: Type 'Invariant' is not assignable to type 'Invariant'. + Types of property 'foo' are incompatible. + Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'. + Type 'keyof B' is not assignable to type 'keyof A'. +tests/cases/conformance/types/conditional/conditionalTypes2.ts(25,5): error TS2322: Type 'Invariant' is not assignable to type 'Invariant'. + Types of property 'foo' are incompatible. + Type 'A extends string ? keyof A : A' is not assignable to type 'B extends string ? keyof B : B'. + Type 'A' is not assignable to type 'B'. + + +==== tests/cases/conformance/types/conditional/conditionalTypes2.ts (4 errors) ==== + interface Covariant { + foo: T extends string ? T : number; + } + + interface Contravariant { + foo: T extends string ? keyof T : number; + } + + interface Invariant { + foo: T extends string ? keyof T : T; + } + + function f1(a: Covariant, b: Covariant) { + a = b; + b = a; // Error + ~ +!!! error TS2322: Type 'Covariant' is not assignable to type 'Covariant'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. + } + + function f2(a: Contravariant, b: Contravariant) { + a = b; // Error + ~ +!!! error TS2322: Type 'Contravariant' is not assignable to type 'Contravariant'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. + b = a; + } + + function f3(a: Invariant, b: Invariant) { + a = b; // Error + ~ +!!! error TS2322: Type 'Invariant' is not assignable to type 'Invariant'. +!!! error TS2322: Types of property 'foo' are incompatible. +!!! error TS2322: Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'. +!!! error TS2322: Type 'keyof B' is not assignable to type 'keyof A'. + b = a; // Error + ~ +!!! error TS2322: Type 'Invariant' is not assignable to type 'Invariant'. +!!! error TS2322: Types of property 'foo' are incompatible. +!!! error TS2322: Type 'A extends string ? keyof A : A' is not assignable to type 'B extends string ? keyof B : B'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. + } + + // Repros from #22860 + + class Opt { + toVector(): Vector { + return undefined; + } + } + + interface Seq { + tail(): Opt>; + } + + class Vector implements Seq { + tail(): Opt> { + return undefined; + } + partition2(predicate:(v:T)=>v is U): [Vector,Vector>]; + partition2(predicate:(x:T)=>boolean): [Vector,Vector]; + partition2(predicate:(v:T)=>boolean): [Vector,Vector] { + return undefined; + } + } + + interface A1 { + bat: B1>; + } + + interface B1 extends A1 { + bat: B1>; + boom: T extends any ? true : true + } + \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes2.js b/tests/baselines/reference/conditionalTypes2.js new file mode 100644 index 0000000000000..5193bae3345d3 --- /dev/null +++ b/tests/baselines/reference/conditionalTypes2.js @@ -0,0 +1,128 @@ +//// [conditionalTypes2.ts] +interface Covariant { + foo: T extends string ? T : number; +} + +interface Contravariant { + foo: T extends string ? keyof T : number; +} + +interface Invariant { + foo: T extends string ? keyof T : T; +} + +function f1(a: Covariant, b: Covariant) { + a = b; + b = a; // Error +} + +function f2(a: Contravariant, b: Contravariant) { + a = b; // Error + b = a; +} + +function f3(a: Invariant, b: Invariant) { + a = b; // Error + b = a; // Error +} + +// Repros from #22860 + +class Opt { + toVector(): Vector { + return undefined; + } +} + +interface Seq { + tail(): Opt>; +} + +class Vector implements Seq { + tail(): Opt> { + return undefined; + } + partition2(predicate:(v:T)=>v is U): [Vector,Vector>]; + partition2(predicate:(x:T)=>boolean): [Vector,Vector]; + partition2(predicate:(v:T)=>boolean): [Vector,Vector] { + return undefined; + } +} + +interface A1 { + bat: B1>; +} + +interface B1 extends A1 { + bat: B1>; + boom: T extends any ? true : true +} + + +//// [conditionalTypes2.js] +"use strict"; +function f1(a, b) { + a = b; + b = a; // Error +} +function f2(a, b) { + a = b; // Error + b = a; +} +function f3(a, b) { + a = b; // Error + b = a; // Error +} +// Repros from #22860 +var Opt = /** @class */ (function () { + function Opt() { + } + Opt.prototype.toVector = function () { + return undefined; + }; + return Opt; +}()); +var Vector = /** @class */ (function () { + function Vector() { + } + Vector.prototype.tail = function () { + return undefined; + }; + Vector.prototype.partition2 = function (predicate) { + return undefined; + }; + return Vector; +}()); + + +//// [conditionalTypes2.d.ts] +interface Covariant { + foo: T extends string ? T : number; +} +interface Contravariant { + foo: T extends string ? keyof T : number; +} +interface Invariant { + foo: T extends string ? keyof T : T; +} +declare function f1(a: Covariant, b: Covariant): void; +declare function f2(a: Contravariant, b: Contravariant): void; +declare function f3(a: Invariant, b: Invariant): void; +declare class Opt { + toVector(): Vector; +} +interface Seq { + tail(): Opt>; +} +declare class Vector implements Seq { + tail(): Opt>; + partition2(predicate: (v: T) => v is U): [Vector, Vector>]; + partition2(predicate: (x: T) => boolean): [Vector, Vector]; +} +interface A1 { + bat: B1>; +} +interface B1 extends A1 { + bat: B1>; + boom: T extends any ? true : true; +} diff --git a/tests/baselines/reference/conditionalTypes2.symbols b/tests/baselines/reference/conditionalTypes2.symbols new file mode 100644 index 0000000000000..4d9cd27238be5 --- /dev/null +++ b/tests/baselines/reference/conditionalTypes2.symbols @@ -0,0 +1,207 @@ +=== tests/cases/conformance/types/conditional/conditionalTypes2.ts === +interface Covariant { +>Covariant : Symbol(Covariant, Decl(conditionalTypes2.ts, 0, 0)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 0, 20)) + + foo: T extends string ? T : number; +>foo : Symbol(Covariant.foo, Decl(conditionalTypes2.ts, 0, 24)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 0, 20)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 0, 20)) +} + +interface Contravariant { +>Contravariant : Symbol(Contravariant, Decl(conditionalTypes2.ts, 2, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 4, 24)) + + foo: T extends string ? keyof T : number; +>foo : Symbol(Contravariant.foo, Decl(conditionalTypes2.ts, 4, 28)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 4, 24)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 4, 24)) +} + +interface Invariant { +>Invariant : Symbol(Invariant, Decl(conditionalTypes2.ts, 6, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 8, 20)) + + foo: T extends string ? keyof T : T; +>foo : Symbol(Invariant.foo, Decl(conditionalTypes2.ts, 8, 24)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 8, 20)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 8, 20)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 8, 20)) +} + +function f1(a: Covariant, b: Covariant) { +>f1 : Symbol(f1, Decl(conditionalTypes2.ts, 10, 1)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 12, 12)) +>B : Symbol(B, Decl(conditionalTypes2.ts, 12, 14)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 12, 12)) +>a : Symbol(a, Decl(conditionalTypes2.ts, 12, 28)) +>Covariant : Symbol(Covariant, Decl(conditionalTypes2.ts, 0, 0)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 12, 12)) +>b : Symbol(b, Decl(conditionalTypes2.ts, 12, 44)) +>Covariant : Symbol(Covariant, Decl(conditionalTypes2.ts, 0, 0)) +>B : Symbol(B, Decl(conditionalTypes2.ts, 12, 14)) + + a = b; +>a : Symbol(a, Decl(conditionalTypes2.ts, 12, 28)) +>b : Symbol(b, Decl(conditionalTypes2.ts, 12, 44)) + + b = a; // Error +>b : Symbol(b, Decl(conditionalTypes2.ts, 12, 44)) +>a : Symbol(a, Decl(conditionalTypes2.ts, 12, 28)) +} + +function f2(a: Contravariant, b: Contravariant) { +>f2 : Symbol(f2, Decl(conditionalTypes2.ts, 15, 1)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 17, 12)) +>B : Symbol(B, Decl(conditionalTypes2.ts, 17, 14)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 17, 12)) +>a : Symbol(a, Decl(conditionalTypes2.ts, 17, 28)) +>Contravariant : Symbol(Contravariant, Decl(conditionalTypes2.ts, 2, 1)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 17, 12)) +>b : Symbol(b, Decl(conditionalTypes2.ts, 17, 48)) +>Contravariant : Symbol(Contravariant, Decl(conditionalTypes2.ts, 2, 1)) +>B : Symbol(B, Decl(conditionalTypes2.ts, 17, 14)) + + a = b; // Error +>a : Symbol(a, Decl(conditionalTypes2.ts, 17, 28)) +>b : Symbol(b, Decl(conditionalTypes2.ts, 17, 48)) + + b = a; +>b : Symbol(b, Decl(conditionalTypes2.ts, 17, 48)) +>a : Symbol(a, Decl(conditionalTypes2.ts, 17, 28)) +} + +function f3(a: Invariant, b: Invariant) { +>f3 : Symbol(f3, Decl(conditionalTypes2.ts, 20, 1)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 22, 12)) +>B : Symbol(B, Decl(conditionalTypes2.ts, 22, 14)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 22, 12)) +>a : Symbol(a, Decl(conditionalTypes2.ts, 22, 28)) +>Invariant : Symbol(Invariant, Decl(conditionalTypes2.ts, 6, 1)) +>A : Symbol(A, Decl(conditionalTypes2.ts, 22, 12)) +>b : Symbol(b, Decl(conditionalTypes2.ts, 22, 44)) +>Invariant : Symbol(Invariant, Decl(conditionalTypes2.ts, 6, 1)) +>B : Symbol(B, Decl(conditionalTypes2.ts, 22, 14)) + + a = b; // Error +>a : Symbol(a, Decl(conditionalTypes2.ts, 22, 28)) +>b : Symbol(b, Decl(conditionalTypes2.ts, 22, 44)) + + b = a; // Error +>b : Symbol(b, Decl(conditionalTypes2.ts, 22, 44)) +>a : Symbol(a, Decl(conditionalTypes2.ts, 22, 28)) +} + +// Repros from #22860 + +class Opt { +>Opt : Symbol(Opt, Decl(conditionalTypes2.ts, 25, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 29, 10)) + + toVector(): Vector { +>toVector : Symbol(Opt.toVector, Decl(conditionalTypes2.ts, 29, 14)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 29, 10)) + + return undefined; +>undefined : Symbol(undefined) + } +} + +interface Seq { +>Seq : Symbol(Seq, Decl(conditionalTypes2.ts, 33, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 35, 14)) + + tail(): Opt>; +>tail : Symbol(Seq.tail, Decl(conditionalTypes2.ts, 35, 18)) +>Opt : Symbol(Opt, Decl(conditionalTypes2.ts, 25, 1)) +>Seq : Symbol(Seq, Decl(conditionalTypes2.ts, 33, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 35, 14)) +} + +class Vector implements Seq { +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>Seq : Symbol(Seq, Decl(conditionalTypes2.ts, 33, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) + + tail(): Opt> { +>tail : Symbol(Vector.tail, Decl(conditionalTypes2.ts, 39, 35)) +>Opt : Symbol(Opt, Decl(conditionalTypes2.ts, 25, 1)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) + + return undefined; +>undefined : Symbol(undefined) + } + partition2(predicate:(v:T)=>v is U): [Vector,Vector>]; +>partition2 : Symbol(Vector.partition2, Decl(conditionalTypes2.ts, 42, 5), Decl(conditionalTypes2.ts, 43, 88), Decl(conditionalTypes2.ts, 44, 64)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 43, 15)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>predicate : Symbol(predicate, Decl(conditionalTypes2.ts, 43, 28)) +>v : Symbol(v, Decl(conditionalTypes2.ts, 43, 39)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>v : Symbol(v, Decl(conditionalTypes2.ts, 43, 39)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 43, 15)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 43, 15)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>Exclude : Symbol(Exclude, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 43, 15)) + + partition2(predicate:(x:T)=>boolean): [Vector,Vector]; +>partition2 : Symbol(Vector.partition2, Decl(conditionalTypes2.ts, 42, 5), Decl(conditionalTypes2.ts, 43, 88), Decl(conditionalTypes2.ts, 44, 64)) +>predicate : Symbol(predicate, Decl(conditionalTypes2.ts, 44, 15)) +>x : Symbol(x, Decl(conditionalTypes2.ts, 44, 26)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) + + partition2(predicate:(v:T)=>boolean): [Vector,Vector] { +>partition2 : Symbol(Vector.partition2, Decl(conditionalTypes2.ts, 42, 5), Decl(conditionalTypes2.ts, 43, 88), Decl(conditionalTypes2.ts, 44, 64)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 45, 15)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>predicate : Symbol(predicate, Decl(conditionalTypes2.ts, 45, 28)) +>v : Symbol(v, Decl(conditionalTypes2.ts, 45, 39)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 39, 13)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) +>U : Symbol(U, Decl(conditionalTypes2.ts, 45, 15)) +>Vector : Symbol(Vector, Decl(conditionalTypes2.ts, 37, 1)) + + return undefined; +>undefined : Symbol(undefined) + } +} + +interface A1 { +>A1 : Symbol(A1, Decl(conditionalTypes2.ts, 48, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 50, 13)) + + bat: B1>; +>bat : Symbol(A1.bat, Decl(conditionalTypes2.ts, 50, 17)) +>B1 : Symbol(B1, Decl(conditionalTypes2.ts, 52, 1)) +>A1 : Symbol(A1, Decl(conditionalTypes2.ts, 48, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 50, 13)) +} + +interface B1 extends A1 { +>B1 : Symbol(B1, Decl(conditionalTypes2.ts, 52, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 54, 13)) +>A1 : Symbol(A1, Decl(conditionalTypes2.ts, 48, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 54, 13)) + + bat: B1>; +>bat : Symbol(B1.bat, Decl(conditionalTypes2.ts, 54, 31)) +>B1 : Symbol(B1, Decl(conditionalTypes2.ts, 52, 1)) +>B1 : Symbol(B1, Decl(conditionalTypes2.ts, 52, 1)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 54, 13)) + + boom: T extends any ? true : true +>boom : Symbol(B1.boom, Decl(conditionalTypes2.ts, 55, 19)) +>T : Symbol(T, Decl(conditionalTypes2.ts, 54, 13)) +} + diff --git a/tests/baselines/reference/conditionalTypes2.types b/tests/baselines/reference/conditionalTypes2.types new file mode 100644 index 0000000000000..e3dad1fc280e5 --- /dev/null +++ b/tests/baselines/reference/conditionalTypes2.types @@ -0,0 +1,218 @@ +=== tests/cases/conformance/types/conditional/conditionalTypes2.ts === +interface Covariant { +>Covariant : Covariant +>T : T + + foo: T extends string ? T : number; +>foo : T extends string ? T : number +>T : T +>T : T +} + +interface Contravariant { +>Contravariant : Contravariant +>T : T + + foo: T extends string ? keyof T : number; +>foo : T extends string ? keyof T : number +>T : T +>T : T +} + +interface Invariant { +>Invariant : Invariant +>T : T + + foo: T extends string ? keyof T : T; +>foo : T extends string ? keyof T : T +>T : T +>T : T +>T : T +} + +function f1(a: Covariant, b: Covariant) { +>f1 : (a: Covariant, b: Covariant) => void +>A : A +>B : B +>A : A +>a : Covariant +>Covariant : Covariant +>A : A +>b : Covariant +>Covariant : Covariant +>B : B + + a = b; +>a = b : Covariant +>a : Covariant +>b : Covariant + + b = a; // Error +>b = a : Covariant +>b : Covariant +>a : Covariant +} + +function f2(a: Contravariant, b: Contravariant) { +>f2 : (a: Contravariant, b: Contravariant) => void +>A : A +>B : B +>A : A +>a : Contravariant +>Contravariant : Contravariant +>A : A +>b : Contravariant +>Contravariant : Contravariant +>B : B + + a = b; // Error +>a = b : Contravariant +>a : Contravariant +>b : Contravariant + + b = a; +>b = a : Contravariant +>b : Contravariant +>a : Contravariant +} + +function f3(a: Invariant, b: Invariant) { +>f3 : (a: Invariant, b: Invariant) => void +>A : A +>B : B +>A : A +>a : Invariant +>Invariant : Invariant +>A : A +>b : Invariant +>Invariant : Invariant +>B : B + + a = b; // Error +>a = b : Invariant +>a : Invariant +>b : Invariant + + b = a; // Error +>b = a : Invariant +>b : Invariant +>a : Invariant +} + +// Repros from #22860 + +class Opt { +>Opt : Opt +>T : T + + toVector(): Vector { +>toVector : () => Vector +>Vector : Vector +>T : T + + return undefined; +>undefined : any +>undefined : undefined + } +} + +interface Seq { +>Seq : Seq +>T : T + + tail(): Opt>; +>tail : () => Opt> +>Opt : Opt +>Seq : Seq +>T : T +} + +class Vector implements Seq { +>Vector : Vector +>T : T +>Seq : Seq +>T : T + + tail(): Opt> { +>tail : () => Opt> +>Opt : Opt +>Vector : Vector +>T : T + + return undefined; +>undefined : any +>undefined : undefined + } + partition2(predicate:(v:T)=>v is U): [Vector,Vector>]; +>partition2 : { (predicate: (v: T) => v is U): [Vector, Vector>]; (predicate: (x: T) => boolean): [Vector, Vector]; } +>U : U +>T : T +>predicate : (v: T) => v is U +>v : T +>T : T +>v : any +>U : U +>Vector : Vector +>U : U +>Vector : Vector +>Exclude : Exclude +>T : T +>U : U + + partition2(predicate:(x:T)=>boolean): [Vector,Vector]; +>partition2 : { (predicate: (v: T) => v is U): [Vector, Vector>]; (predicate: (x: T) => boolean): [Vector, Vector]; } +>predicate : (x: T) => boolean +>x : T +>T : T +>Vector : Vector +>T : T +>Vector : Vector +>T : T + + partition2(predicate:(v:T)=>boolean): [Vector,Vector] { +>partition2 : { (predicate: (v: T) => v is U): [Vector, Vector>]; (predicate: (x: T) => boolean): [Vector, Vector]; } +>U : U +>T : T +>predicate : (v: T) => boolean +>v : T +>T : T +>Vector : Vector +>U : U +>Vector : Vector + + return undefined; +>undefined : any +>undefined : undefined + } +} + +interface A1 { +>A1 : A1 +>T : T + + bat: B1>; +>bat : B1> +>B1 : B1 +>A1 : A1 +>T : T +} + +interface B1 extends A1 { +>B1 : B1 +>T : T +>A1 : A1 +>T : T + + bat: B1>; +>bat : B1> +>B1 : B1 +>B1 : B1 +>T : T + + boom: T extends any ? true : true +>boom : T extends any ? true : true +>T : T +>true : true +>true : true +} + diff --git a/tests/cases/conformance/types/conditional/conditionalTypes2.ts b/tests/cases/conformance/types/conditional/conditionalTypes2.ts new file mode 100644 index 0000000000000..5ba189236b05b --- /dev/null +++ b/tests/cases/conformance/types/conditional/conditionalTypes2.ts @@ -0,0 +1,61 @@ +// @strict: true +// @declaration: true + +interface Covariant { + foo: T extends string ? T : number; +} + +interface Contravariant { + foo: T extends string ? keyof T : number; +} + +interface Invariant { + foo: T extends string ? keyof T : T; +} + +function f1(a: Covariant, b: Covariant) { + a = b; + b = a; // Error +} + +function f2(a: Contravariant, b: Contravariant) { + a = b; // Error + b = a; +} + +function f3(a: Invariant, b: Invariant) { + a = b; // Error + b = a; // Error +} + +// Repros from #22860 + +class Opt { + toVector(): Vector { + return undefined; + } +} + +interface Seq { + tail(): Opt>; +} + +class Vector implements Seq { + tail(): Opt> { + return undefined; + } + partition2(predicate:(v:T)=>v is U): [Vector,Vector>]; + partition2(predicate:(x:T)=>boolean): [Vector,Vector]; + partition2(predicate:(v:T)=>boolean): [Vector,Vector] { + return undefined; + } +} + +interface A1 { + bat: B1>; +} + +interface B1 extends A1 { + bat: B1>; + boom: T extends any ? true : true +}