TypeScript-联合类型、交叉类型

112 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第13天,点击查看活动详情

前言

TypeScript 在开发中,除了基本的内置类型之外,更多时候需要的是由内置类型通过一定方式组合而成的新类型,或者叫做自定义类型。

一般有四种方式用于创建自定义类型:联合交叉索引映射

最近正好学习到了这一部分,总结记录一下,先来聊聊联合类型交叉类型

联合类型

主要标志就是使用 | 运算符,类似逻辑运算的操作, 表示满足指定类型的任意一种即可,比如:

type Union = number | string

微信截图_20220813114934.png
表示 Union 类型可以是 number 或者 string,这里两个类型的值都符合 Union 的要求。

但也有一些特殊的情况,如下:

type Union1 = number | any | string

联合类型中存在 any 时,Union1 只会是 any 类型,因为 any 本身就包含着所有的内置类型,也就包含着 numberstring,所以最后会被推导为一个 any

微信截图_20220813114732.png

当联合类型中存在 unknown,与 any 也是同理,因为 unknown 类型的值也可以是任何类型,自然也就包括 number,所以会被推导为 unknown:

type Union2 = number | unknown

微信截图_20220813115407.png

当联合类型中存在 never 时,never 会被忽略掉;

type Union3 = number | never | string

微信截图_20220813115658.png
因为 never 本身代表什么都没有,没有任何数据可以赋值给 never 类型,所以,联合类型中会将其剔除。

交叉类型

主要标志是使用 & 运算符,类似逻辑运算的操作,表示要同时满足全部的指定类型,比如:

type Cross = { name: string } & { age: number }

微信截图_20220813135845.png

上面代码意味着 Cross 这个类型的对象,必须同时拥有 nameage 这两个属性,并且属性的值还得分别是 stringnumber

但是如果对象中的存在相同的属性,并且属性的值的类型不同,则会变成 never:

type Cross = { name: string } & { age: number, name: boolean } // never

微信截图_20220813145417.png

需要注意的是,内置类型的交叉类型基本都是 never:

type Cross1 = number & string // never
type Cross2 = string & boolean // never
type Cross3 = string & symbol // never
type Cross4 = number & object // never
type Cross5 = number & null // never
type Corss6 = number & undefined // never
type Cross7 = object & null // never
type Cross8 = number & never // never

因为不可能存在一个数据既是 A 又是 B 的,所以全部都为 never

当然,也有特殊情况,当交叉类型存在 any 时,结果皆为 any:

type Cross8 = any & number // any

微信截图_20220813143828.png

never 也是如此,甚至连 any & never 的结果都是 never:

微信截图_20220813144318.png

而与 unknown 参与的 交叉类型anynever 相反,类似于 联合类型 中的 never,本身会被忽略掉:

type Cross14 = number & unknown // number
type Cross15 = string & unknown // string
type Cross16 = any & unknown // any
type Cross17 = never & unknown // never