一. 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 } }
以上就是typescript中的联合类型使用示例详解的详细内容,更多关于typescript联合类型的资料请关注代码网其它相关文章!
发表评论