TypeScript 实现 Exclude

1,723 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

TypeScript 动手实现 Exclude

在学习学个各种前端框架源码的时候,发现框架当中有许多各种各样的高级类型,就有种非常想要学习的心情,恰好在逛 Github 的时候,无意中发现了这个项目:type-challenges,随机便开始刷起了 TypeScript 的类型体操。

这篇文章,我们就手动来实现一个 Eclude 的题目,恰好对应原题地址:github.com/type-challe…

也欢迎大家和我一起共同学习!

Exclude 的作用

在 ts 中,我们能够使用 Exclude<T,U> 这个工具,帮助我们把 T 类型当中属于 U 类型的部分去除后得到一个新的类型,ts 已经自己提供了,使用方式如下:

type myType = Exclude<'a' | 'b' | 'c', 'a'>

得到的 myType'b'|'c',明白 Exclude 的作用以后就可以自己手动实现一个了

MyExclude 的实现

首先我们使用 js 来实现,假设 Exclude 为一个函数,类型在这里就当作参数传入函数,返回值作为得到的类型,代码如下所示:

/**
 * T: ['a', 'b', 'c']
 * U: ['a']
 */
function MyExclude(T: any[], U: any[]) {
  const result = []
  for (let i = 0; i < T.length; i++) {
    const temp = T[i]
    if (!U.includes(temp)) {
      result.push(temp)
    }
  }
  return result
}

const T = ['a', 'b', 'c']
const U = ['a']
MyExclude(T, U) // ['b', 'c']

有上述的函数代码可以知道,在获得最终类型的时候,必定会经过循环,在 ts 中使用 extends 关键字可以实现,ts 的代码实现如下 :

type MyExclude<T, U> = T extends U ? never : T

对比过程,大概原理就如同下面的表格所示:

TUResult
aanever
bab
cac

T 当中的每一项,取出与 U 当中的每一项进行比较,相同返回 never,不同则返回 T 当中的项