- 类型保护就是一些表达式,他们在编译的时候就能通过类型信息确保某个作用域内变量的类型
- 类型保护就是能够通过关键字判断出分支中的类型
typeof 类型保护
function fn(a:string|number): void {if (typeof a == 'number') {console.log('number')} else {console.log('string')}}
instanceof 类型保护
```typescript class Animal { } class Dog extends Animal { } class Cat extends Animal { }
function getName(animal: Animal): Animal { if (animal instanceof Dog) { return ‘dog’; } else { return ‘cat’; } }
<a name="oKJL8"></a># null 保护如果开启了strictNullChecks选项,那么对于可能为null的变量不能调用它上面的方法和属性```typescriptfunction getStr(str: string | null) {str = str || '';return str;}
链判断运算符
- 链判断运算符是一种先检查属性是否存在,再尝试访问该属性的运算符,其符号为 ?.
如果运算符左侧的操作数 ?. 计算为 undefined 或 null,则表达式求值为 undefined 。否则,正常触发目标属性访问,方法或函数调用。
a?.b; //如果a是null/undefined,那么返回undefined,否则返回a.b的值.
链判断运算符 还处于 stage1 阶段,TS 也暂时不支持
可辨识的联合类型
就是利用联合类型中的共有字段进行类型保护的一种技巧
- 相同字段的不同取值就是可辨识
上面的接口我们声明的好像是一个对象。。。interface WarningButton {class: 'warning';text1: '修改';}interface DangerButton {class: 'danger';text2: '删除';}type Button = WarningButton | DangerButton;function getButton(button: Button) {if (button.class == 'warning') {console.log(button.text1);}if (button.class == 'danger') {console.log(button.text2);}}
interface User {username: string}type Action = {type:'add',payload:User} | {type: 'delete'payload: number}const UserReducer = (action: Action) => {switch (action.type) {case "add":let user: User = action.payload;break;case "delete":let id: number = action.payload;break;default:break;}};
in操作符
in 运算符可以被用于参数类型的判断 ```typescript interface Bird { swing: number }
interface Dog { leg: number } function getNumber(x: Bird | Dog) { if (‘swing’ in x) { return x.swing } return x.leg; }
<a name="JT5qD"></a># 自定义的类型保护- TypeScript 里的类型保护本质上就是一些表达式,它们会在运行时检查类型信息,以确保在某个作用域里的类型是符合预期的- type is Type1Class就是类型谓词- 谓词为 parameterName is Type这种形式,parameterName必须是来自于当前函数签名里的一个参数名- 每当使用一些变量调用isType1时,如果原始类型兼容,TypeScript会将该变量缩小到该特定类型```typescriptinterface Person {leg: number}interface Dog {leg: number}function isPerson(x: Person | Dog): x is Person {return x.leg == 2;}function getType(x: Person | Dog) {if (isPerson(x)) {console.log('这是个人');} else {console.log('这是条狗');}}const p: Person = { leg: 2 };getType(p); // '这是个人'
unknown
- TypeScript 3.0 引入了新的unknown 类型,它是 any 类型对应的安全类型
unknown 和 any 的主要区别是 unknown 类型会更加严格:在对 unknown 类型的值执行大多数操作之前,我们必须进行某种形式的检查。而在对 any 类型的值执行操作之前,我们不必进行任何检查
any
在 TypeScript 中,任何类型都可以被归为 any 类型。这让 any 类型成为了类型系统的 顶级类型 (也被称作 全局超级类型)。
- TypeScript允许我们对 any 类型的值执行任何操作,而无需事先执行任何形式的检查 ```typescript let value: any;
value = true; // OK value = 42; // OK value = “Hello World”; // OK value = []; // OK value = {}; // OK value = Math.random; // OK value = null; // OK value = undefined; // OK
let value: any; value.foo.bar; // OK value.trim(); // OK value(); // OK new value(); // OK
<a name="LF0ii"></a>## unknown 类型- 就像所有类型都可以被归为 any,所有类型也都可以被归为 unknown。这使得 unknown 成为 TypeScript 类型系统的另一种顶级类型(另一种是 any)- 任何类型都可以赋值给unknown类型```typescriptlet value: unknown;value = true; // OKvalue = 42; // OKvalue = "Hello World"; // OKvalue = []; // OKvalue = {}; // OKvalue = Math.random; // OKvalue = null; // OKvalue = undefined; // OKvalue = new TypeError(); // OK
unknown类型只能被赋值给any类型和unknown类型本身
let value: unknown;let value1: unknown = value; // OKlet value2: any = value; // OKlet value3: boolean = value; // Errorlet value4: number = value; // Errorlet value5: string = value; // Errorlet value6: object = value; // Errorlet value7: any[] = value; // Errorlet value8: Function = value; // Error
缩小 unknown 类型范围
- 如果没有类型断言或类型细化时,不能在unknown上面进行任何操作
- typeof
- instanceof
- 自定义类型保护函数
- 可以对 unknown 类型使用类型断言
const value: unknown = "Hello World";const someString: string = value as string;
联合类型中的 unknown 类型
在联合类型中,unknown 类型会吸收任何类型。这就意味着如果任一组成类型是 unknown,联合类型也会相当于 unknowntype UnionType1 = unknown | null; // unknowntype UnionType2 = unknown | undefined; // unknowntype UnionType3 = unknown | string; // unknowntype UnionType4 = unknown | number[]; // unknown
交叉类型中的 unknown 类型
在交叉类型中,任何类型都可以吸收 unknown 类型。这意味着将任何类型与 unknown 相交不会改变结果类型type IntersectionType1 = unknown & null; // nulltype IntersectionType2 = unknown & undefined; // undefinedtype IntersectionType3 = unknown & string; // stringtype IntersectionType4 = unknown & number[]; // number[]type IntersectionType5 = unknown & any; // any
never是unknown的子类型
keyof unknown 等于never
只能对unknown进行等或不等操作,不能进行其它操作
映射类型
```typescript type getType= {
};
let obj = {
a: 1,
b: ‘’,
c: false
};
type c = getType
我们查看下 c 是什么类型?<br /><br />如果映射类型遍历的时候是unknown,不会映射属性```typescripttype getType<T> = {[P in keyof T]:number}type t = getType<unknown>;
结果如下,可以看到 t 是一个空对象:
