将多个类型合并为一个类型,新的类型将具有所有类型的特性,所以交叉类型是所有类型的并集。
// 交叉类型是所有类型的并集
interface IPerson {
id: string;
age: number;
}
interface IWorker {
companyId: string;
}
type IStaff = IPerson & IWorker;
const staff: IStaff = {
id: 'E1006', age: 33,
companyId: 'EXE'
};
console.dir(staff)
interface DogInterface {
run(): void;
}
interface CatInterface {
jump(): void;
}
let pet: DogInterface & CatInterface = {
run() {},
jump() {},
};
联合类型
声明的类型并不确定,可以为多个类型中的一个。所以联合类型取所有类型中的交集。
字面量联合类型
let a: number | string = 'a';
let b: 'a' | 'b' | 'c'; // 字面量联合类型
let c: 1 | 2 | 3; // 字面量联合类型
对象联合类型
class Dog implements DogInterface {
run() {}
eat() {}
}
class Cat implements CatInterface {
jump() {}
eat() {}
}
enum Master { Boy, Girl };
function getPet(master: Master) {
// pet类型被推断为Dog和Cat的联合类型
let pet = master === Master.Boy ? new Dog() : new Cat();
// 如果一个对象是联合类型,在类型未确定的情况下,只能访问所有类型的共有成员(取所有类型的交集)
pet.eat();
// pet.run(); 这个方法是不能使用的
return pet;
}
可区分的联合类型
本质上讲,是一种结合了联合类型和字面量类型的一种类型保护方法。
一个类型如果是多个类型的联合类型,并且每个类型之间有一个公共的属性,那么我们就可以凭借这个公共属性创建不同的类型保护区块。
interface Square {
kind: 'square';
size: number;
}
interface Rectangle {
kind: 'rectangle';
width: number;
height: number;
}
type Shape = Square | Rectangle;
function area(s: Shape) {
switch (s.kind) {
case 'square':
return s.size * s.size;
case 'rectangle':
return s.height * s.width;
}
}
这些代码不去升级没有问题,但如果加一种新的类型,就会出现隐患。
解决办法:
1、给函数指定一个明确的返回值类型,此时ts会判断所有的switch分支是不是包含了所有的情况。
2、利用never类型
interface Square {
kind: 'square';
size: number;
}
interface Rectangle {
kind: 'rectangle';
width: number;
height: number;
}
interface Circle {
kind: 'circle',
r: number;
}
type Shape = Square | Rectangle | Circle;
function area(s: Shape) {
// function area(s: Shape): number { // 1) 给函数指定一个明确的返回值类型,此时ts会判断所有的switch分支是不是包含了所有的情况
switch (s.kind) {
case 'square':
return s.size * s.size;
case 'rectangle':
return s.height * s.width;
case 'circle':
return Math.PI * s.r;
default: // 2)
return ((e: never) => { throw new Error(e); })(s); // 该函数的作用是检查s是否是never类型。若s是never类型,表示前面的分支都覆盖了,则default分支永远不会执行到;
}
}
console.log(area({kind: 'circle', r: 1}));
|
请发表评论