Weird TypeScript conditional types, is this a bug?

78 Views Asked by At

I am seeing discrepancies between individual versus nested condition types in TypeScript. The code below highlights the issue:

type Equal<T, U> = T[] extends U[] ? U[] extends T[] ? true : false : false;
type IsAssignable<V, T> = T extends V ? true : false;
type IsFalse<T extends boolean> = IsAssignable<false[], T[]>;
type And<T extends boolean, U extends boolean> = IsFalse<T> extends true ? false : IsFalse<U> extends true ? false : T | U;

type TestType = string;
const test1: And<true, false> = false;
const test2: And<true, false> = true; // as expected: Type 'true' is not assignable to type 'false'.(2322)

const test3: Equal<TestType, number> = false;
const test4: Equal<TestType, number> = true; // as expected: Type 'true' is not assignable to type 'false'.(2322)

const test5: Equal<TestType, string> = false; // as expected: Type 'false' is not assignable to type 'true'.(2322)
const test6: Equal<TestType, string> = true;

// writing it out manually yields the expected result
const expected1: And<Equal<TestType, string>, Equal<TestType, number>> = false;
const expected2: And<Equal<TestType, string>, Equal<TestType, number>> = true; // as expected: Type 'true' is not assignable to type 'false'.(2322)

// but now the weird part, defining a shortcut
type shortcut<T> = And<Equal<T, string>, Equal<T, number>>;

// ...causes the returned result to be boolean (true | false) instead!
const weird1: shortcut<TestType> = false; // no compilation error!
const weird2: shortcut<TestType> = true; // no compilation error!

Can someone explain? Oh, and before someone points it out... I am aware that the definition of of Equal is different from the usual [T] extends [U] form, but this should work equivalently to my current understanding. If not, I'd be curious exactly why not. Thank you very much in advance!

Link: TypeScript Playground

Can somebody please shed light on what's going on here?

0

There are 0 best solutions below