never, unknown, any 三者之间的区别
三者都是 TypeScript 的类型, never 是最具体的类型,因为没有哪个集合比空集合更小了;而 unknown 是最弱的类型,因为它包含了全部可能的值。 any 则不为集合,它破坏了类型检查,因此请尽量不要使用 any。在 TypeScript 中, nerver 可以赋值为 unknown 和 any ,但是 unknown 和 any 不可以赋值给 never,never 只能赋值 never。
那 nerver 的作用是什么呢?举个尤雨溪提到的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| interface Foo { type: "foo"; }
interface Bar { type: "bar"; }
type All = Foo | Bar;
function handleValue(val: All) { switch (val.type) { case "foo": break; case "bar": break; default: const exhaustiveCheck: never = val; break; } }
|
注意在 default 里面我们把被收窄为 never 的 val 赋值给一个显式声明为 never 的变量。如果一切逻辑正确,那么这里应该能够编译通过。但是假如后来有一天你的同事改了 All 的类型:
1
| type All = Foo | Bar | Baz;
|
然而他忘记了在 handleValue 里面加上针对 Baz 的处理逻辑,这个时候在 default branch 里面 val 会被收窄为 Baz,导致无法赋值给 never,产生一个编译错误。所以通过这个办法,你可以确保 handleValue 总是穷尽 (exhaust) 了所有 All 的可能类型。
interface 与 type 的区别
相同点:
都可以描述一个对象或者函数
1 2 3 4 5 6 7 8 9
| interface User { name: string; age: number; }
interface SetUser { (name: string, age: number): void; }
|
1 2 3 4 5 6 7
| type User = { name: string; age: number; };
type SetUser = (name: string, age: number) => void;
|
都允许扩展
1 2 3 4 5 6
| interface Name { name: string; } interface User extends Name { age: number; }
|
1 2 3 4
| type Name = { name: string; }; type User = Name & { age: number };
|
不同点
type 可以而 interface 不行
type 可以声明基本类型别名,联合类型,元组等类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| type Name = string;
interface Dog { wong(); } interface Cat { miao(); }
type Pet = Dog | Cat;
type PetList = [Dog, Pet];
|
type 语句中还可以使用 typeof 获取实例的 类型进行赋值
1 2 3
| let div = document.createElement("div"); type B = typeof div;
|
其它用法
1 2 3 4 5 6 7
| type StringOrNumber = string | number; type Text = string | { text: string }; type NameLookup = Dictionary<string, Person>; type Callback<T> = (data: T) => void; type Pair<T> = [T, T]; type Coordinates = Pair<number>; type Tree<T> = T | { left: Tree<T>; right: Tree<T> };
|
interface 可以而 type 不行
interface 能够声明合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| interface User { name: string; age: number; }
interface User { sex: string; }
|