# 交叉类型与联合类型

# 交叉类型

定义:交叉类型就是取多个类型的并集,表示这个类型同时具备这几个连接起来的类型的特点;

用法:使用 & 符号定义,被&符链接的多个类型构成一个交叉类型,来看例子:

const merge = <T, U>(arg1: T, arg2: U): T & U => {
  let res = <T & U>{}; // 这里指定返回值的类型兼备T和U两个类型变量代表的类型的特点
  res = Object.assign(arg1, arg2); // 这里使用Object.assign方法,返回一个合并后的对象;
                                   // 关于该方法,请在例子下面补充中学习
  return res;
};

const info1 = {
  name: "imooc"
};

const info2 = {
  age: 18
};

const lisonInfo = merge(info1, info2);

console.log(lisonInfo.address); // error 类型“{ name: string; } & { age: number; }”上不存在属性“address”

补充阅读:Object.assign方法可以合并多个对象,将多个对象的属性添加到一个对象中并返回;

如果属性值是对象或者数组这种保存的是内存引用的引用类型,会保持这个引用,也就是如果在Object.assign返回的的对象中修改某个对象属性值,原来用来合并的对象也会受到影响。

可以看到,传入的两个参数分别是带有属性 name 和 age 的两个对象,所以它俩的交叉类型要求返回的对象既有 name 属性又有 age 属性。

# 联合类型

定义:联合类型实际是几个类型的结合,但是和交叉类型不同,联合类型是要求只要符合联合类型中任意一种类型即可。

用法:它使用 | 符号定义;

应用场景:当我们的程序具有多样性,元素类型不唯一时,即使用联合类型。

const getLength = (content: string | number): number => {
  if (typeof content === "string") return content.length;
  else return content.toString().length;
};

console.log(getLength("abc")); // 3
console.log(getLength(123)); // 3

这里我们指定参数既可以是字符串类型也可以是数值类型,这个getLength函数的定义中,其实还涉及到一个知识点,就是类型保护,就是typeof content === “string”,后面会扩展介绍。