前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【TS】506- TypeScript 交叉类型

【TS】506- TypeScript 交叉类型

作者头像
pingan8787
发布2020-03-02 15:07:59
1.8K0
发布2020-03-02 15:07:59
举报
文章被收录于专栏:前端自习课前端自习课

一、简介

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

代码语言:javascript
复制
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 这两种类型的成员。那么现在问题来了,假设在合并多个类型的过程中,刚好出现某些类型存在相同的成员,但对应的类型又不一致,比如:

代码语言:javascript
复制
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 类型呢?比如下面的例子:

代码语言:javascript
复制
p = { c: 6, d: "d", e: "e" };
代码语言:javascript
复制
q = { c: "c", d: "d", e: "e" };

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

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

代码语言:javascript
复制
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 接口

代码语言:javascript
复制
export interface ArgBase<T> {
  name?: string;
  description?: string;
  hidden?: boolean;
  parse: ParseFn<T>;
  default?: T | (() => T);
  input?: string;
  options?: string[];
}

RequiredArg 接口

代码语言:javascript
复制
export type RequiredArg<T> = ArgBase<T> & {
  required: true;
  value: T;
}

OptionalArg 接口

代码语言:javascript
复制
export type OptionalArg<T> = ArgBase<T> & {
  required: false;
  value?: T;
}

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

三、参考资源

  • tslang-advanced-types
  • typescript-intersection-types
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端自习课 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、简介
    • 二、使用示例
      • 三、参考资源
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档