4TypeScript的联合类型
一. TS类型系统有哪些运算
- 联合类型,以下是具体的例子,理解成集合的并集
type A1 = number;
type B1 = string;
type C1 = A1 | B1;
const c1: C1 = 42;
// 这种可以理解成集合的并集,但是他们没有交集
type A2 = { name: string };
// 这里要理解成 A2表示name为string的所有对象,比如{name: 'a', age: 14}, 它既可以有age也可以没age
type B2 = { age: number };
type C2 = A2 | B2;
const c2: C2 = {
name: 'John',
age: 18,
};
// 这种可以理解成两个集合的并集,并且他们有交集
二. 如何使用联合类型?
- 用的时候必须拆开,不然只能用number和string同时拥有的方法或者属性
- 这种缩小类型范围的过程我们叫做类型收窄(narrowing)
const f1 = (a: number | string) => {
if (typeof a === 'number') {
a.toFixed();
} else {
a.split(',');
}
};
三. typeof的局限性
- typeof 作用于数组对象,普通对象,日期对象,null都是返回object
四. 使用instanceof来区分类型
const f1 = (a: Date | Date[]) => {
if (a instanceof Date) {
a;
} else {
a;
}
};
五. instanceof的缺点
- 不支持string,number,boolean等基本类型
- 我们可以将instanceof 和 typeof结合解决这个问题
const f1 = (a: Date | string | Date[]) => {
if (typeof a === 'string') {
a;
} else if (a instanceof Date) {
a;
} else {
a;
}
};
- 不支持TS独有的类型,也就是那些会被擦除的类型
- 用in解决,但是这个方案也只能解决部分问题,比如无法区分两个函数
type Person = {
name: string;
};
type Animal = {
x: string;
};
const f1 = (a: Person | Animal) => {
if('name' in a) {
a
} else if ('x' in a) {
a
} else {
a
}
}
- ts官方文档上也介绍了一些收窄类型的方案
六. ts中的区分类型方法 以上所讲都是根据js中的方式来区分类型,接下来我们讨论下ts中的类型区分方法
-
- 类型谓词/类型判断 is, is的优点支持所有ts类型,is的缺点麻烦。
type Rect = {
height: number;
width: number;
};
type Circle = {
center: [number, number];
radius: number;
};
const f1 = (a: Rect | Circle) => {
if (isRect(a)) {
a;
}
};
// 这里x is Rect就是类型谓词,用于收窄类型,写boolean不行,因为这里写boolean的话ts不知道boolean的含义是什么
function isRect(x: Rect | Circle): x is Rect {
return 'height' in x && 'width' in x;
}
-
- 使用可辨别联合类型,加字段来表示,好处让复杂类型的收窄变成简单类型的对比
- 可以使用这种方式的条件 T = A | B | C | D ...
-
- A,B,C,D...有相同属性kind或其它
-
- kind的类型是简单类型
-
- 各类型中的kind可区分
- 总结: 我们需要一个同名,可辨别的简单类型的key,这样的T类型我们称为可辨别联合类型
-
type Circle = { kind: 'Circle'; center: [number, number] };
type Square = { kind: 'Square'; sideLength: number };
// 两个联合起来的类型通过加上kind字段来进行判断类型
type Shape = Circle | Square;
const f1 = (a: string | number | Shape) => {
if (typeof a === 'string') {
a;
} else if (typeof a === 'number') {
a;
} else if (a.kind === 'Circle') {
a;
} else {
a;
}
};
- 补充一个使用可辨别联合类型的场景
- 在react中我们会经常这样写,比如对一个用户增删改查
type Action =
| { type: 'getUser'; id: string }
| { type: 'createUser'; attributes: any }
| { type: 'deleteUser'; id: string }
| { type: 'updateUser'; attributes: any };
-
- 使用断言
type Circle = { kind: 'Circle'; center: [number, number] };
type Square = { kind: 'Square'; x: number };
type Shape = Circle | Square;
const f1 = (a: Shape) => {
(a as Circle).center; // 这就是断言
};
f1({ kind: 'Circle', center: [1, 2] });
七. any是否是所有类型(除了never/unknown/any/void)的联合?为什么?
- 不是,因为一旦两个类型联合起来,只能用此两个类型共有的方法,而any可以使用所有类型的方法
const f1 = (a: number | string) => {
a.toFixed(); // 会报错
a.split(); // 会报错
a.toString(); // 只能用number和string共有的方法
};
const f2 = (a: any) => {
a.toFixed(); // 不会报错
a.split(); // 不会报错
};
- any有点像法外狂徒,ts绝大部分规则对any不生效
const f1 = (a: any) => {
const b: never = a; // 会报错,这算是any唯一不能违反的规则
};
- 那么什么是所有类型(除了never/unknown/any/void)的联合
- unknown,因为unknown可以收窄到任何类型,也就是说它是任何类型的联合
const f1 = (a: unknown) => {
if(a instanceof Date) {
a // Date
}
if(isPerson(a)) {
a // Person
}
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbakij
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01