//// [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 } // Extract is a T that is known to be a Function function isFunction(value: T): value is Extract { return typeof value === "function"; } function getFunction(item: T) { if (isFunction(item)) { return item; } throw new Error(); } function f10(x: T) { if (isFunction(x)) { const f: Function = x; const t: T = x; } } function f11(x: string | (() => string) | undefined) { if (isFunction(x)) { x(); } } function f12(x: string | (() => string) | undefined) { const f = getFunction(x); // () => string f(); } type Foo = { foo: string }; type Bar = { bar: string }; declare function fooBar(x: { foo: string, bar: string }): void; declare function fooBat(x: { foo: string, bat: string }): void; type Extract2 = T extends U ? T extends V ? T : never : never; function f20(x: Extract, Bar>, y: Extract, z: Extract2) { fooBar(x); fooBar(y); fooBar(z); } function f21(x: Extract, Bar>, y: Extract, z: Extract2) { fooBat(x); // Error fooBat(y); // Error fooBat(z); // 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 } // Repro from #22899 declare function toString1(value: object | Function): string ; declare function toString2(value: Function): string ; function foo(value: T) { if (isFunction(value)) { toString1(value); toString2(value); } } // Repro from #23052 type A = T extends object ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A; } : T extends V ? T : never; type B = T extends object ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B; } : T extends V ? T : never; type C = { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; // Repro from #23100 type A2 = T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; type B2 = T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; type C2 = T extends object ? { [Q in keyof T]: C2; } : T; // Repro from #28654 type MaybeTrue = true extends T["b"] ? "yes" : "no"; type T0 = MaybeTrue<{ b: never }> // "no" type T1 = MaybeTrue<{ b: false }>; // "no" type T2 = MaybeTrue<{ b: true }>; // "yes" type T3 = MaybeTrue<{ b: boolean }>; // "yes" // Repro from #28824 type Union = 'a' | 'b'; type Product = { f1: A, f2: B}; type ProductUnion = Product<'a', 0> | Product<'b', 1>; // {a: "b"; b: "a"} type UnionComplement = { [K in Union]: Exclude }; type UCA = UnionComplement['a']; type UCB = UnionComplement['b']; // {a: "a"; b: "b"} type UnionComplementComplement = { [K in Union]: Exclude> }; type UCCA = UnionComplementComplement['a']; type UCCB = UnionComplementComplement['b']; // {a: Product<'b', 1>; b: Product<'a', 0>} type ProductComplement = { [K in Union]: Exclude }; type PCA = ProductComplement['a']; type PCB = ProductComplement['b']; // {a: Product<'a', 0>; b: Product<'b', 1>} type ProductComplementComplement = { [K in Union]: Exclude> }; type PCCA = ProductComplementComplement['a']; type PCCB = ProductComplementComplement['b']; // Repro from #31326 type Hmm = U extends T ? { [K in keyof U]: number } : never; type What = Hmm<{}, { a: string }> const w: What = { a: 4 }; // Repro from #33568 declare function save(_response: IRootResponse): void; exportCommand(save); declare function exportCommand(functionToCall: IExportCallback): void; interface IExportCallback { (response: IRootResponse): void; } type IRootResponse = TResponse extends IRecord ? IRecordResponse : IResponse; interface IRecord { readonly Id: string; } declare type IRecordResponse = IResponse & { sendRecord(): void; }; declare type IResponse = { sendValue(name: keyof GetAllPropertiesOfType): void; }; declare type GetPropertyNamesOfType = { [PropertyName in Extract]: T[PropertyName] extends RestrictToType ? PropertyName : never }[Extract]; declare type GetAllPropertiesOfType = Pick< T, GetPropertyNamesOfType, RestrictToType> >; // Repro from #33568 declare function ff(x: Foo3): void; declare function gg(f: (x: Foo3) => void): void; type Foo3 = T extends number ? { n: T } : { x: T }; gg(ff); // Repro from #41613 type Wat = { x: { y: 0, z: 1 } } extends { x: { [P in K]: 0 } } ? true : false; type Huh = Wat<"y">; // 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 } // Extract is a T that is known to be a Function function isFunction(value) { return typeof value === "function"; } function getFunction(item) { if (isFunction(item)) { return item; } throw new Error(); } function f10(x) { if (isFunction(x)) { var f = x; var t = x; } } function f11(x) { if (isFunction(x)) { x(); } } function f12(x) { var f = getFunction(x); // () => string f(); } function f20(x, y, z) { fooBar(x); fooBar(y); fooBar(z); } function f21(x, y, z) { fooBat(x); // Error fooBat(y); // Error fooBat(z); // 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; }()); function foo(value) { if (isFunction(value)) { toString1(value); toString2(value); } } var w = { a: 4 }; exportCommand(save); gg(ff); //// [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 function isFunction(value: T): value is Extract; declare function getFunction(item: T): Extract; declare function f10(x: T): void; declare function f11(x: string | (() => string) | undefined): void; declare function f12(x: string | (() => string) | undefined): void; declare type Foo = { foo: string; }; declare type Bar = { bar: string; }; declare function fooBar(x: { foo: string; bar: string; }): void; declare function fooBat(x: { foo: string; bat: string; }): void; declare type Extract2 = T extends U ? T extends V ? T : never : never; declare function f20(x: Extract, Bar>, y: Extract, z: Extract2): void; declare function f21(x: Extract, Bar>, y: Extract, z: Extract2): 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; } declare function toString1(value: object | Function): string; declare function toString2(value: Function): string; declare function foo(value: T): void; declare type A = T extends object ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: A; } : T extends V ? T : never; declare type B = T extends object ? { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: B; } : T extends V ? T : never; declare type C = { [Q in { [P in keyof T]: T[P] extends V ? P : P; }[keyof T]]: C; }; declare type A2 = T extends object ? T extends any[] ? T : { [Q in keyof T]: A2; } : T; declare type B2 = T extends object ? T extends any[] ? T : { [Q in keyof T]: B2; } : T; declare type C2 = T extends object ? { [Q in keyof T]: C2; } : T; declare type MaybeTrue = true extends T["b"] ? "yes" : "no"; declare type T0 = MaybeTrue<{ b: never; }>; declare type T1 = MaybeTrue<{ b: false; }>; declare type T2 = MaybeTrue<{ b: true; }>; declare type T3 = MaybeTrue<{ b: boolean; }>; declare type Union = 'a' | 'b'; declare type Product = { f1: A; f2: B; }; declare type ProductUnion = Product<'a', 0> | Product<'b', 1>; declare type UnionComplement = { [K in Union]: Exclude; }; declare type UCA = UnionComplement['a']; declare type UCB = UnionComplement['b']; declare type UnionComplementComplement = { [K in Union]: Exclude>; }; declare type UCCA = UnionComplementComplement['a']; declare type UCCB = UnionComplementComplement['b']; declare type ProductComplement = { [K in Union]: Exclude; }; declare type PCA = ProductComplement['a']; declare type PCB = ProductComplement['b']; declare type ProductComplementComplement = { [K in Union]: Exclude>; }; declare type PCCA = ProductComplementComplement['a']; declare type PCCB = ProductComplementComplement['b']; declare type Hmm = U extends T ? { [K in keyof U]: number; } : never; declare type What = Hmm<{}, { a: string; }>; declare const w: What; declare function save(_response: IRootResponse): void; declare function exportCommand(functionToCall: IExportCallback): void; interface IExportCallback { (response: IRootResponse): void; } declare type IRootResponse = TResponse extends IRecord ? IRecordResponse : IResponse; interface IRecord { readonly Id: string; } declare type IRecordResponse = IResponse & { sendRecord(): void; }; declare type IResponse = { sendValue(name: keyof GetAllPropertiesOfType): void; }; declare type GetPropertyNamesOfType = { [PropertyName in Extract]: T[PropertyName] extends RestrictToType ? PropertyName : never; }[Extract]; declare type GetAllPropertiesOfType = Pick, RestrictToType>>; declare function ff(x: Foo3): void; declare function gg(f: (x: Foo3) => void): void; declare type Foo3 = T extends number ? { n: T; } : { x: T; }; declare type Wat = { x: { y: 0; z: 1; }; } extends { x: { [P in K]: 0; }; } ? true : false; declare type Huh = Wat<"y">;