TS学习3-联合类型和交叉类型
Contents
TS = JS + 类型系统
- TS类型系统的运算主要有两种:或(|)运算和与(&)运算
1 联合类型(并集)
1.1 示例
|
可以属于x类型,也可以属于y类型
|
|
1.2 类型收窄
1.2.1 JS中的类型区分
-
使用联合类型就涉及到类型的区分,也就是类型收窄(Narrow)
-
使用
typeof
1 2 3 4 5 6 7 8 9
const f1 = (a: number | string) => { if(typeof a === 'number'){ a.toFixed(2) } else if (typeof a === 'string') { a.split('') } else { throw new Error('Never do this') } }
- 缺点:无法区分
Date
、null
、Array
和普通对象(都是object
)
- 缺点:无法区分
-
使用
instanceof
- 不支持
TS
独有的类型(会被擦除)
1 2 3 4
type Person = { name: string } const f1 = (a:Person | Person[]) => { if(a instanceof Person) // X 报错 }
- 不支持
string
、number
、boolean
- 不支持
-
使用
in
1 2 3 4
type Person = { name: string } const f1 = (a:Person | Person[]) => { if('name' in a) }
- 只适用于部分普通对象
-
使用类的判断类型方法:
Array.isArray()
-
1.2.2 类型谓词/类型判断
- TS中区分类型的万全之法一:类型谓词/类型判断
- 为了解决以上方案的通病:不支持TS独有的类型,需要使用类型谓词is搭配自定义类型判断函数
- 说白了就是把类型判断函数提取出来,加上is,使这个方法得到TS支持
|
|
1.2.3 可辩别联合
- 同名、可辩别的简单类型的key,则称作可辩别联合
- 代码看起来比较傻
|
|
1.3 法外狂徒any
- any是所有类型(never、unknown、any、void除外)的联合吗?为什么?
- 不是,联合类型必须做类型收窄后才能正常使用,否则只能使用联合类型共有的属性
- 而any是不需要的,可以随意使用各种属性,TS不会报错的
- TS大部分规则对any不生效
1.4 重新认识unknown
- unknown是所有类型(never、unknown、any、void除外)的联合类型
- 只要做类型收窄,就可以正常使用
2 交叉类型(交集)
2.1 理解type A = { name: string }
-
表示A类型是一个具有name属性,且值为string类型的对象
-
注意措辞,是
具有
,而不是只有
,因此以下都属于A类型{ name: 'gsq', age: 10 }
{ name: 'gsq', gender: 'man' }
-
注意当初始化时,TS会报错,但在赋值时是不会的
|
|
2.2 交叉类型示例
&
既属于x类型又属于y类型
|
|
2.3 属性冲突(无交集)
- 示例
|
|
- 使用
type + &
在使用时才会报错 - 使用
interface + extends
在定义时就会报错
2.4 总结
-
交叉类型常用于有交集的类型A、B
-
如果A、B无交集,可能得到never,或者属性为never
Author gsemir
LastMod 2022-10-12