1
type A = {
  a: number;
  b: string;
};
type B = {
  b: number;
  c: boolean;
};

I have test the extends relationship, It shows true:

type Expected1 = Pick<A & B, keyof A | keyof B> extends A & B ? true : false; // true
type Expected2 = A & B extends Pick<A & B, keyof A | keyof B> ? true : false; // true

But got falsy with Equal type:

type Equal<X, Y> =
  (<T>() => T extends X ? 1 : 2) extends
  (<T>() => T extends Y ? 1 : 2) ? true : false

type Expected3 = Equal<A & B, Pick<A & B, keyof A | keyof B>> // false

Can anyone tell me why?

Community
  • 1
  • 1
phill zou
  • 23
  • 4
  • I've typically seen `Equal` written as the far simpler `type Equal = X extends Y ? Y extends X ? true : false : false` which does return `true` here. https://tsplay.dev/wQKQjm Not 100% sure why that equality check fails though. – Alex Wayne Sep 12 '21 at 06:53
  • Attach a [reference link](https://stackoverflow.com/questions/68961864/how-does-the-equals-work-in-typescript/68963796#68963796) about this `Equal` type – phill zou Sep 12 '21 at 08:05

1 Answers1

1

That Equal function devised by mattmccutchen did not pass test H in this Github issue

type A = number == string;// false
type B = 1 == 1;// true
type C = any == 1;// false
type D = 1 | 2 == 1;// false
type E = Head<[1,2,3]> == 1;// true(see:#24897)
type F = any == never;// false
type G = [any] == [number];// false
type H = {x:1}&{y:2} == {x:1,y:2}// true

Here's a solution that makes creative use of the assignability rule for conditional types, which requires that the types after extends be "identical" as that is defined by the checker:

export type Equals<X, Y> = (() => T extends X ? 1 : 2) extends (() => T extends Y ? 1 : 2) ? true : false;

This passes all the tests from the initial description that I was able to run except H, which fails because the definition of "identical" doesn't allow an intersection type to be identical to an object type with the same properties. (I wasn't able to run test E because I don't have the definition of Head.)

Your example falls into the case of H perfectly.

Here is the original github comment link: https://github.com/Microsoft/TypeScript/issues/27024#issuecomment-421529650

glinda93
  • 7,659
  • 5
  • 40
  • 78