Could you explain how does Equal
type implementation work?
#9100
-
type-challenges/utils/index.d.ts Line 7 in e3cc0d3 |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 1 reply
-
As a first thought, let's talk about assignability: type Assignable<X, Y> = X extends Y ? true : false This tests for assignability of So what about mutual assignability? Can we use the following type? type MutuallyAssignable<X, Y> = X extends Y ? Y extends X ? true : false : false Actually not. Mutual assignability does not guarantee type equality: type X1 = { a: string, b?: boolean }
type X2 = { a: string, c?: number }
type X1X2 = MutuallyAssignable<X1, X2> // literal type true
function x1x2(x1: X1, x2: X2) {
// Mutual assignability:
x1 = x2; // ok
x2 = x1; // ok
// Type inequality:
x1.b = x2.b; // error: Property 'b' does not exist on type 'X2'.
x2.c = x1.c; // error: Property 'c' does not exist on type 'X1'.
} Fortunately, for some set of types,
(1) is true because literal types have only one value. (2) is true because (4) means that two types are equal if they share the same assignable types (and if they also share the same non-assignable types). To continue the example from above, as type X1E1 = { a: string, c: string }
function x1x2e1(x1: X1, x2: X2, e1: X1E1) {
x1 = e1; // ok
x2 = e1; // error: Type 'E1' is not assignable to type 'X2'.
// Types of property 'c' are incompatible.
// Type 'string' is not assignable to type 'number'.
} With these observations in mind, we can find the implementation of T extends X ? 1 : 2 But (4) tells us that we need to do the classification for all types <T>() => T extends X ? 1 : 2 But now we are classifying non-argument function return types although we would compare the function types themselves. (3) shows that this is equivalent to comparing their return types, so we found a suitable comparer type for checking type equality and can define
Actually, we now make a classification to either This is the actual implementation of Note: This is an excerpt from my solution to the |
Beta Was this translation helpful? Give feedback.
-
It really helps me, thanks for your sharing @sbr61 But one thing still confuse me, please look at these codes: type M<T> = <N>() => N extends T ? 1 : 2;
type Y = M<unknown>;
type YY = M<any>;
type R = Y extends YY ? 1 : 0
|
Beta Was this translation helpful? Give feedback.
As a first thought, let's talk about assignability:
This tests for assignability of
X
toY
instead of testing for equality.So what about mutual assignability? Can we use the following type?
Actually not. Mutual assignability does not guarantee type equality: