Closed
Description
TypeScript Version: 3.8.0-dev.20200206
Search Terms:
conditional boolean
Code
type Example1<T> = () => T;
type Example2<T> = T extends any ? () => T : never;
type Example3<T> = T extends never ? never : () => T;
function test1<T>(e: Example1<T>): void {}
function test2<T>(e: Example2<T>): void {}
function test3<T>(e: Example3<T>): void {}
test1(() => 1); // ok
test2(() => 1); // ok
test3(() => 1); // ok
test1(() => ''); // ok
test2(() => ''); // ok
test3(() => ''); // ok
test1(() => true); // ok
test2(() => true); // fail
test3(() => true); // fail
test3(() => false); // fail
test3(() => true as true); // ok
// root cause: with boolean, conditional type is inferred to be:
type FalseOrTrueReturn = (() => false) | (() => true)
const falseOrTrueReturn: FalseOrTrueReturn = () => (false as boolean) // fail
// it only fails for function return type, so this works:
type FalseOrTrueArg = ((value: false) => void) | ((value: true) => void)
const falseOrTrueArg: FalseOrTrueArg = (value: boolean) => {} // ok
Expected behavior:
All failing lines should compile just fine. This is a simplified example, but it prevents correct type inference for more complex real-world use-cases.
Actual behavior:
Compiler fails to compile the lines with a function returning a boolean. This is due to the boolean return value being destructured into () => true | () => false
, and () => boolean
is not assignable to that.
Playground Link:
TS Playground