const
Pet
=
getPet
();
Pet
.
layEggs
();
Pet
.
fly
();
使用基于
in
操作符判断的类型守卫
if
(
'fly'
in
Pet
) {
Pet
.
fly
();
2. intersection 交叉类型
出了逻辑或,和js一样 类型也存在逻辑与 "&" 表示交叉类型, 很显然如果我们仅仅把一些基础类型 执行&操作 其类型就会声明出一些"不存在"类型 因为任何类型都不能满足同时属于多种原子类型,比如既是 string 类型又是 number 类型。 因此,这些"不存在"的类型就是个 never。
交叉类型还可以把接口交叉 理解成接口类型求并集所得到的类型
合并的多个接口类型 可以将多个接口类型求并集得到的结果
type IntersectionTypeConfict = { id: number; name: string; } & { age: number; sex: string; };
const mixedConflict: IntersectionTypeConfict = {
id: 1,
sex: '男',
age: 2,
name: '123'
合并的多个接口类型中存在同名属性会是什么效果?
可以分为两种情况:
同名属性兼容: 兼容的同名属性 合并后会是两者类型的子类型 (同 type name = string & '2' // '2' 类型 )
同名属性不兼容: 不兼容的合并后会得到 never类型 (同 type name = string & number //never类型)
合并联合类型 (将联合类型交叉 === 联合类型求交集)
合并联合类型后 生成类型需要同时满足不同的联合类型限制 也就是提取了所有联合类型的相同类型成员 可以将合并联合类型理解为求两个联合类型的交集
type UnionA = 'a' | 'b' | 'c' | 'd';
type UnionB = 'c' | 'd' | 'e' | 'f';
type UnionC = UnionA & UnionB
3. 联合、交叉类型本身就可以直接组合使用
联合、交叉运算符不仅在行为上表现一致,还在运算的优先级和 JavaScript 的逻辑或 ||、逻辑与 && 运算符上表现一致
联合操作符 | 的优先级低于交叉操作符 &,同样,我们可以通过使用小括弧 () 来调整操作符的优先级
进而,我们也可以把分配率、交换律等基本规则引入类型组合中,然后优化出更简洁、清晰的类型
4. 类型缩减
如果将 string 原始类型和“string字面量类型”组合成联合类型会是什么效果?效果就是类型缩减成 string 了
type a = string | 'string' => type a = string
同样对于 number boolean 枚举类型 也有一样的类型缩减逻辑
type URStr = 'string' | string;
type URNum = 2 | number;
type URBoolen = true | boolean;
enum EnumUR {
ONE,
type URE = EnumUR.ONE | EnumUR;
ts把字面量类型、枚举成员类型缩减掉,只保留原始类型、枚举类型等父类型,这是合理的“优化”。
但是对与IDE中的提示, 这个缩减很大地削弱了自动提示的能力 如下代码 BorderColor 只会提示成 string类型 所有的字符串字面量 black、red 等都无法自动提示出来了 ts官方提供一个黑魔法 可以让类型缩减被控制 只需要
在父类型后面添加 &{} 即可
type BorderColor = 'black' | 'red' | 'green' | 'yellow' | 'blue' | string;
type BorderColor2 = 'black' | 'red' | 'green' | 'yellow' | 'blue' | string & {};
同样当联合类型的成员是接口类型 如果满足其中一个接口的属性是另外一个接口属性的子集,这个属性也会类型缩减
type UnionInterce = { age: "1" } | { age: "1" | "2"; [key: string]: string };
思考: 如何定义如下所示 age 属性是数字类型,而其他不确定的属性是字符串类型的数据结构的对象(利用类型缩减)?
age: 1,
anyProperty: 'str',
复制代码