专栏首页前端自习课【TS】506- TypeScript 交叉类型

【TS】506- TypeScript 交叉类型

一、简介

TypeScript 交叉类型是将多个类型合并为一个类型。这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。

interface IPerson {
  id: string;
  age: number;
}

interface IWorker {
  companyId: string;
}

type IStaff = IPerson & IWorker;

const staff: IStaff = {
  id: 'E1006',  age: 33,
  companyId: 'EXE'
};

console.dir(staff)

在上面示例中,我们首先为 IPerson 和 IWorker 类型定义了不同的成员,然后通过 & 运算符定义了 IStaff 交叉类型,所以该类型同时拥有 IPerson 和 IWorker 这两种类型的成员。那么现在问题来了,假设在合并多个类型的过程中,刚好出现某些类型存在相同的成员,但对应的类型又不一致,比如:

interface X {
  c: string;
  d: string;
}

interface Y {
  c: number;
  e: string
}

type XY = X & Y;
type YX = Y & X;

let p: XY;
let q: YX;

在上面的代码中,接口 X 和接口 Y 都含有一个相同的成员 c,但它们的类型不一致。对于这种情况,此时 XY 类型或 YX 类型中成员 c 的类型是不是可以是 stringnumber 类型呢?比如下面的例子:

p = { c: 6, d: "d", e: "e" };
q = { c: "c", d: "d", e: "e" };

为什么接口 X 和接口 Y 混入后,成员 c 的类型会变成 never 呢?这是因为混入后成员 c 的类型为 string&number,即成员 c 的类型既是 string 类型又是number 类型。很明显这种类型是不存在的,所以混入后成员 c 的类型为 never

在上面示例中,刚好接口 X 和接口 Y 中内部成员 c 的类型都是基本数据类型,那么如果是非基本数据类型的话,又会是什么情形。我们来看个具体的例子:

interface D { d: boolean; }
interface E { e: string; }
interface F { f: number; }

interface A { x: D; }
interface B { x: E; }
interface C { x: F; }

type ABC = A & B & C;

let abc: ABC = {
    x: {
      d: true,
      e: 'semlinker',
      f: 666
    }
};

console.log('abc:', abc);

以上代码成功运行后,控制台会输出以下结果:

由上图可知,在混入多个类型时,若存在相同的成员,且成员类型为非基本数据类型,那么是可以成功合并。前面我们已经介绍了 TypeScript 交叉类型相关的知识,最后我们再来举一个实际的使用示例。

二、使用示例

在实际项目开发过程中,我们经常需要开发一些功能函数,为了保证函数的灵活性和可复用性,这些函数往往会定义一些输入参数,而这些参数根据是否必填,又可分为必填参数和可选参数。当必填参数和可选参数有大部分参数是相同的情况下,我们就可以利用 TypeScript 交叉类型来解决复用问题。好了,废话不多说,直接看个示例:

ArgBase 接口

export interface ArgBase<T> {
  name?: string;
  description?: string;
  hidden?: boolean;
  parse: ParseFn<T>;
  default?: T | (() => T);
  input?: string;
  options?: string[];
}

RequiredArg 接口

export type RequiredArg<T> = ArgBase<T> & {
  required: true;
  value: T;
}

OptionalArg 接口

export type OptionalArg<T> = ArgBase<T> & {
  required: false;
  value?: T;
}

顾名思义,ArgBase 接口是基础参数接口,它是 RequiredArg 和 OptionalArg 接口的公共部分。示例代码中,RequiredArg 和 OptionalArg 的差异就是 required 字段和与之对应的 value 值。通过交叉类型,可以让我们更好地进行代码复用,并方便地实现把多种类型叠加到一起成为一种新的类型。

三、参考资源

  • tslang-advanced-types
  • typescript-intersection-types

本文分享自微信公众号 - 前端自习课(FE-study)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-02-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【算法】228-每周一练 之 数据结构与算法(Set)

    这些都是数据结构与算法,一部分方法是团队其他成员实现的,一部分我自己做的,有什么其他实现方法或错误,欢迎各位大佬指点,感谢。

    pingan8787
  • 【TS】358- 浅析 TypeScript 设计模式

    设计模式就是软件开发过程中形成的套路,就如同你在玩lol中的“正方形打野”,“四一分推”,又或者篮球运动中的“二夹一”,“高位单打”一样,属于经验的总结。

    pingan8787
  • Hybrid App 应用 开发中 9 个必备知识点复习(WebView / 调试 等)

    我们大前端团队内部 ?每周一练 的知识复习计划继续加油,本篇文章是 《Hybrid APP 混合应用专题》 主题的第二期和第三期的合集。

    pingan8787
  • 以太坊区块链 Asp.Net Core的安全API设计 (上)

    去中心化应用程序(DApp)的常见设计不仅依赖于以太坊区块链,还依赖于API层。在这种情况下,DApp通过用户的以太坊帐户与智能合约进行交互,并通过交换用户凭据...

    笔阁
  • 干货 | Taro 开发微信小程序入门与实战

    如果你是 Vue 开发者,但又不想过多的折腾,继续沿用 Vue 的开发方式来开发小程序,那么用 mpvue 将会是你的最明智的选择。同时也支持一些第三方 UI ...

    极乐君
  • 学术资讯| 打破国际AI胸部多器官分割记录,腾讯优图荣获SegTHOR三项冠军

    全球AI辅助胸部多器官分割技术取得新突破。近日,全球胸部多器官分割大赛SegTHOR Challenge 2019(Segmentation of Thorac...

    优图实验室
  • 精华 | 140种Python标准库、第三方库和外部工具都有了

    【导读】Python数据工具箱涵盖从数据源到数据可视化的完整流程中涉及到的常用库、函数和外部工具。其中既有Python内置函数和标准库,又有第三方库和工具。

    AI科技大本营
  • 吐血整理!140种Python标准库、第三方库和外部工具都有了

    文件的读写包括常见的txt、Excel、xml、二进制文件以及其他格式的数据文本,主要用于本地数据的读写。

    华章科技
  • 140种Python标准库、第三方库和外部工具

    这些库可用于文件读写、网络抓取和解析、数据连接、数清洗转换、数据计算和统计分析、图像和视频处理、音频处理、数据挖掘/机器学习/深度学习、数据可视化、交互学习和集...

    用户7886150
  • 通宵整理的140种Python标准库、第三方库和外部工具都有!

    这些库可用于文件读写、网络抓取和解析、数据连接、数清洗转换、数据计算和统计分析、图像和视频处理、音频处理、数据挖掘/机器学习/深度学习、数据可视化、交互学习和集...

    一墨编程学习

扫码关注云+社区

领取腾讯云代金券