Skip to content

Latest commit

 

History

History

0645-Diff-medium

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

0645 Diff

关键词: TypeScript, TypeChallenge

实现Diff类, 接受两个类型作为参数, 返回二者不同名的属性的集合

举个栗子

type A = {
  foo: string;
  bar: number;
  a: Function;
};
type B = {
  foo: string;
  bar: boolean;
  b: symbol;
};

type D = Diff<A, B>;
/* 
type D = {
  a: Function;
  b: symbol;
}
*/

答案

type Diff<A, B> = {
  [K in keyof A | keyof B as Exclude<K, keyof A & keyof B>]:
    K extends keyof A
      ? A[K]
      : K extends keyof B
        ? B[K]
        : never;
};

分析

keyof A记作Ak, keyof B记作Bk

AkBk的并集 减去 AkBk的交集 即为二者不同的属性名, 对于其中的每一个属性, 判断它是来自A 还是来自B, 据此找出其来源的类型并使用之即可

type Diff<A, B> = {
  //                                    A B 的交集
  // -----------------------------------∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨∨
  [K in keyof A | keyof B as Exclude<K, keyof A & keyof B>]:
  // ---^^^^^^^^^^^^^^^^^
  //    A B 的并集
    K extends keyof A // 如果来自 A
      ? A[K] // 取 A 中对应的类型
      : K extends keyof B // 如果来自 B
        ? B[K] // 取 A 中对应的类型
        : never; // 不可能到这一步