类型保护就是一些表达式,可以在编译的时候就能通过类型信息确保某个作用域内变量的类型;
类型保护就是能够通过关键字判断出分支中的类型;
typeof 类型保护
function double(input: string | number) {
if (typeof input === 'string') console.log('string');
if (typeof input === "number") console.log('number');
}
instanceof 类型保护
class Animal { }
class Bird extends Animal { }
class Dog extends Animal { }
function getName(animal: Animal) {
if (animal instanceof Bird) console.log('bird');
if (animal instanceof Dog) console.log('dog');
}
null 保护
function getFirstLetter(s: string | null) {
// if (s === null) return ''; // 第一种方式
// s = s || ''; // 第二种方式
return s!.charAt(0); // 第三种强行断言不为 null,如果 s 为 null 还是会报错
}
链判断运算符
let a = { b: 2 }
let result = a?.b; // a === null ? undefined : a.b;
let x = 'b';
a?.[x];
a?.[x]()
可辨识的联合类型
interface WarningButton {
class: 'waring',
text1: '修改'
}
interface DangerButton {
class: 'danger',
text2: '删除'
}
type Button = WarningButton | DangerButton;
function getButton(button: Button) {
if (button.class === 'waring') console.log(button);
if (button.class === "danger") console.log(button);
}
in 操作符
interface Admin {
name: string;
privileges: string[];
}
interface Employee {
name: string;
startDate: Date;
}
function printInfo(emp: Employee | Admin) {
if ("privileges" in emp) console.log("Privileges");
if ("startDate" in emp) console.log("Start Date");
}
自定义的类型保护
interface Bird {
swing: number; // 2 条腿
}
interface Dog {
leg: number; // 4 条腿
}
// 类型谓词 parameterName is Type
// 自定义类型判断 y 是 Bird,返回值为 true => y 是 Bird 类型
const isBird = (y: Bird | Dog): y is Bird => (y as Bird).swing === 2;
function getAnimal(x: Bird | Dog) {
if (isBird(x)) console.log('bird');
else console.log('dog');
}
// 用 TypeScript 的另一个特性泛型,来解决复用问题
function isNil<T>(v: T | undefined | null): v is undefined | null {
return v === undefined || v === null;
}
function numberFun(v: number | undefined | null) {
// number 类型
if (!isNil(v)) console.log(Math.round(v));
}
function stringFun(v: string | undefined | null) {
// string 类型
if (!isNil(v)) console.log(v.toLocaleLowerCase());
}
unknown
// 任何类型的值可以赋值给 any,同时 any 类型的值也可以赋值给任何类型
let value: any;
value = true;
value = 1;
value = [];
value.foo()
value.length;
// unknown:是 any 的安全类型
// 任何类型的值都可以赋值给 unknown,但 unknown 只能赋值给 unknown 和 any 类型
let value2: unknown;
value2 = true;
value2 = 1;
value2 = [];
value2 = 'hello';
value2.foo(); // 对象的类型为 "unknown"
value2.length; // 对象的类型为 "unknown"
联合类型中的 unknown 类型
// 联合类型中的 unknown 不管跟谁联系,最后都是 unknown
type U1 = unknown | null;
type U2 = unknown | undefined;
type U3 = unknown | string;
type U4 = unknown | number[];
兼容性
上一篇