I tried to make static analysis of types (like std::type_traits
) with TypeScript, and first I made is_same<>
.
Classes and primitive types work fine, but String Literal Types have strange behavior.
type is_same<A, B> = A extends B ? B extends A ? true : false : false;
type _1 = is_same<"a" | "b", "a" | "b">;
type _2 = "a" | "b" extends "a" | "b" ? "a" | "b" extends "a" | "b" ? true : false : false;
The type obtained using is_same<>
is _1
. This type is boolean
.
Next, The result of expanding is_same<>
is _2
. This type is true
.
What is the difference between these results?
I confirmed with TypeScript 4.7.4.
CodePudding user response:
The problem here is caused by Distributive Conditional Types.
By chaining the conditionals here the way you did, each member of the union is distributed individually to the next conditional.
To stop this, you can wrap A
and B
in a tuple.
type is_same<A, B> = [A] extends [B] ? B extends A ? true : false : false;