diff --git a/tests/cases/conformance/types/conditional/conditionalTypes2.ts b/tests/cases/conformance/types/conditional/conditionalTypes2.ts index 5ba189236b0..c3418cf924d 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes2.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes2.ts @@ -28,6 +28,56 @@ function f3(a: Invariant, b: Invariant) { 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 { @@ -59,3 +109,15 @@ 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); + } +}