I feel the conditional types are very powerful. I want to leverage it to do more complex and dynamic checking.
I want to check if given 2 generics are equal.
I saw this solution on Typescript's issues.
type MyEquals<X, Y> =
(<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2)
? true
: false
type res1 = MyEquals<true, false> // false, values
type res2 = MyEquals<true, true> // true, values
type res3 = MyEquals<boolean, boolean> // true, primitive types
type res4 = MyEquals<Promise<string>, Promise<string>> // true, advanced/custom types
I don't understand why the function <T>() => T notation and the primitives aren't functions so how is this type giving me a true/false on those values.
Can someone explain me how this MyEquals works and does it really work for all types?
Another solution stated in the same issue:
type EqualsWrapped<T> = T extends infer R & {}
? {
[P in keyof R]: R[P]
}
: never
export type Equals<A, B> = (<T>() => T extends EqualsWrapped<A> ? 1 : 2) extends
(<T>() => T extends EqualsWrapped<B> ? 1 : 2)
? true
: false
Here I don't understand what does T extends infer R & {} actually do?
Isn't extends supposed to do a structural check {a: string} == {a: number}(resulting in false) kind of a check?
And infer is supposed to be used to target Item of an Array or Property of an Object, right? So what are we inferring here if T isn't a Object or Array?
Sorry for so many questions.