# 定义 持续补充

Typescript 提供的实用工具类型并不能完全满足我们的需求,很多时候,我们都需要自定义一些满足我们需求的工具类型。

# 集合的操作

# 交集

定义: 对于给定的两个集合,返回一个包含两个集合中共有元素的新集合。

我们可以借助Pick (opens new window)Extract (opens new window)来实现。

type Intersection<T extends object, U extends object> = Pick<
  T,
  Extract<keyof T, keyof U> & Extract<keyof U, keyof T>
>
1
2
3
4

直接体验 (opens new window)

# 并集

定义: 对于给定的两个集合,返回一个包含两个集合中所有元素的新集合。

// 合并交叉类型
type Compute<T extends any> = T extends Function
  ? T
  : { [K in keyof T]: T[K] }

// P1: { name: string, age: string }
// P2: { name: string, gender: string }
// Res => { name: string, age: string } & { gender: string }
//     => { name: string, age: string, gender: string }
type Merge<T extends object, U extends object> = Compute<
  T & Omit<U, keyof T>
>
1
2
3
4
5
6
7
8
9
10
11
12

# demo

type P1 = {
  name: string,
  age: string
}
type P2 = {
  name: string,
  age: number,
  gender: string
}

type Intersection<
    T extends object,
    U extends object
> = Pick<
    T,
    Extract<keyof T, keyof U> & Extract<keyof U, keyof T>
>

// { name: string, age: string }
type P = Intersection<P1, P2>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# demo

type P1 = {
  name: string,
  age: string
}
type P2 = {
  name: string,
  age: number,
  gender: string
}

type Compute<T extends any> = T extends Function ? T : {
    [K in keyof T]: T[K]
}

type Merge<T extends object, U extends object> = Compute<
    T & Omit<U, keyof T>
>

// { name: string; age: string; gender: string; }
type P = Merge<P1, P2>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

直接体验 (opens new window)

这里合并之后会发现,age 属性是使用前面属性的类型,这里如何解决呢?

# Overwrite

type Overwrite<
  T extends object,
  U extends object,
  I = Diff<T, U> & Intersection<U, T>
> = Pick<I, keyof I>
1
2
3
4
5

# demo

type P1 = {
  name: string,
  age: string
}
type P2 = {
  name: string,
  age: number,
  gender: string
}

type Intersection<
    T extends object,
    U extends object
> = Pick<
    T,
    Extract<keyof T, keyof U> & Extract<keyof U, keyof T>
>

type Diff<
  T extends object,
  U extends object
> = Pick<
  T,
  Exclude<keyof T, keyof U>
>

type Compute<T extends any> = T extends Function ? T : {
  [K in keyof T]: T[K]
}

type Merge<T extends object, U extends object> = Compute<
  T & Omit<U, keyof T>
>

type Overwrite<
  T extends object,
  U extends object,
  I = Diff<T, U> & Intersection<U, T>
> = Pick<I, keyof I>

type P = Overwrite<P1, P2>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

直接体验 (opens new window)

# 差集

定义: 对于给定的两个集合,返回一个包含所有存在于第一个且不存在于第二个集合的元素的新集合。

type Diff<T extends object, U extends object> = Pick<
  T,
  Exclude<keyof T, keyof U>
>
1
2
3
4

# demo

type P1 = {
  name: string,
  age: string
}
type P2 = {
  name: string,
  age: number,
  gender: string
}

type Diff<
    T extends object,
    U extends object
> = Pick<
    T,
    Exclude<keyof T, keyof U>
>

// { gender: string }
type P = Diff<P2, P1>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

直接体验 (opens new window)

# 快来耍耍啊

# 🌰🌰

// template
1

# 游乐场


# 参考答案

// answer
1

# 参考资料