- A+
所属分类:Web前端
前言:学习一门新的知识,首要的问题就是概念,这里记录下
一. [any, unkonw] 的区别
- any 不做类型判断,可以任意 [赋值,使用]
1 let _a: any = "1"; // ok 2 _a = 1; // ok 3 console.log(_a.split); // ok
- unknow 可以任意赋值,但是在使用的时候会做类型推断,如果可能发生错误,就会及时阻止;因此,使用前要用 [instanceof, typeof] 做类型缩窄
1 let _b: unknown = 1; 2 _b = "1"; // ok 3 if (_b instanceof Number) { 4 console.log(_b.toPrecision); // ok,因为已经做了类型缩窄 5 } 6 if (typeof _b == "string") { 7 console.log(_b.split); // ok,因为这里也做了类型缩窄 8 } 9 10 console.log(_b.toString); // ok,toString 是所有类型共有的,因此类型推断不会发生错误 11 console.log(_b.toPrecision); // Property 'toPrecision' does not exist on type 'unknown'. // toPrecision 是数字类型特有的,因此在类型推断的时候及时报错了
- 总结:unknow 看起来比 any 更安全
二. [viod, never] 的区别
- void 表示空,可以赋值为 [null, undefined]
1 let _c: void = null; // ok 2 _c = undefined; // ok 3 _c = 1; // Type 'number' is not assignable to type 'void'. // void 不是数字的子类
- never 表示永远不会出现,它的作用在于推断类型是否穷尽,没有穷尽就会及时报错,是为了避免意外的非同步修改;下面这段代码是可以编译通过的,因为 switch 已经穷尽了 All 类型,永远不会执行到 default
1 interface Foo { 2 type: "foo"; 3 } 4 interface Bar { 5 type: "bar"; 6 } 7 type All = Foo | Bar; 8 9 function handleValue(val: All) { 10 switch (val.type) { 11 case "foo": 12 // 这里 val 被收窄为 Foo 13 break; 14 case "bar": 15 // val 在这里是 Bar 16 break; 17 default: 18 // val 在这里是 never 19 const exhaustiveCheck: never = val; 20 break; 21 } 22 }
现在我声明一个 Baz,并且添加到 All,但是忘记同步添加 switch...case...,因此有可能执行到 default,所以及时报错
- 总结:void 表示空,是包含了 [null, undefined] 的集合;never 表示永远不会出现,是一个空集,当有一种可能,使它不再是空集的时候,它就会报错
三. [extends, implements] 的区别
- extends 表示继承,implements 表示实现
1 interface Animal { 2 eat(): void; 3 } 4 5 interface Cat extends Animal { 6 climb(): void; 7 } 8 9 class Animal implements Animal { 10 eat(): void { 11 "eat"; 12 } 13 } 14 15 class Cat extends Animal implements Cat { 16 climb(): void { 17 "climb"; 18 } 19 }
- 总结:class 可以继承 class,interface 可以继承 interface,class 可以实现 interface;class 表示具体,interface 表示抽象
四. [type, interface] 的异同
- 相同点,示例
1 // 都可以声明对象 2 type _c = {}; 3 interface _d {} 4 5 // 都可以声明函数 6 type _e = () => void; 7 interface _f { 8 (): void; 9 } 10 11 // 都可以继承 12 // interface 继承 interface 13 interface _g extends _d {} 14 15 // type 继承 interface 16 type _h = _d & {}; 17 18 // interface 继承 type 19 interface _i extends _c {} 20 21 // type 继承 type 22 type _j = _c & {}; 23 24 // 都可以实现 25 class _k implements _c, _d {}
- type 可以声明 [基本类型,联合类型,元组],interface 不可以,示例
1 type _aa = string; 2 type _bb = string | number; 3 type _cc = [string, number];
- interface 会合并同名接口,type 不允许声明同名接口,示例
1 interface _dd { 2 username: string; 3 } 4 interface _dd { 5 age: number; 6 } 7 8 class _ee implements _dd { 9 username: "g"; 10 age: 1; 11 } 12 13 type _ff = {}; // Duplicate identifier '_ff'. 14 type _ff = {}; // Duplicate identifier '_ff'.
- 总结:type 的粒度更细,可控性更强;interface 只能定义对象和函数,并且有一些智能行为,可控性比 type 弱
五. 结尾
在学习阶段,对概念性的东西做基本的区分是很有必要的,这是讨论问题和继续进步的基础!