打字稿中的 'Pick<A & B, keyof A | keyof B> ' 和 'A & B' 有什么区别

What's the difference between 'Pick<A & B, keyof A | keyof B> ' and 'A & B' in typescript

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

我已经测试了 extends 关系,它显示 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

但是 Equal 类型是假的:

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

谁能告诉我为什么?

mattmccutchen did not pass test H in this Github issue

设计的 Equal 函数
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.)

你的例子完全符合H的情况。

这是原始的 github 评论 link:https://github.com/Microsoft/TypeScript/issues/27024#issuecomment-421529650