TypeScript 中的类型(下)
何时使用 enum
实例一:用 A.todo
将数字映射成一个有意义的语法
实例二:可以用于表示权限
以上代码中,Manage = Read | Write | Delete
是 JS 中的二进制操作(二进制或运算符),0b
在 JS 中表示二进制
何时用 enum 会显得很呆?
如上所示,将 'apple'
映射为 Fruit.apple
完全是多此一举,还是别再用 enum
来映射字符串了吧ヾ(-_-;)
只推荐用
enum
对数字做映射,除此之外都不推荐使用enum
何时使用 type
TS 中的 Type
叫作类型别名,Type Aliases,其实就是给其他类型取个名字,示例如下:
1 | type Name = string; |
如何体现出 type
只是一个别名?
1 | type X = { x: number } |
以上 TS 代码中 A 的类型是?
由于 type
只是一个别名,并不是声明了一个真正的类型,此处 A
的类型为 { x: number }
如何理解 type FalseLike = '' | 0 | false | null | undefined
?
上面的五个值其实都是类型,类型可以理解为集合,因此可以看作五个集合并在一起,每个集合中只包含一个值;另外,不支持 NaN
作为类型,因为 NaN
表示的是一个值而不是类型
带有属性的函数的声明方式
1 | type FnWithProps = { |
多用于 React 中
何时使用 interface
声明接口,用于描述对象的属性 declare the shapes of objects
1 | interface Data { [k: string]: string; } |
type
如何实现继承?
1 | interface X { age: number; } |
type 和 interface 的区别
区别一
interface
只能描述对象,而 type
能描述所有数据类型
区别二
type
并不会创建一个新的类型,只是创建了一个类型别名;而 interface
则是类型声明,会创建一个新的类型
1 | type A = string; |
区别三
type
不可重新赋值,因此不能存在同名的 type
;而 interface
可以声明同名的类型,同名的 interface
会自动合并
1 | type A = string; // 报错 Duplicate identifier 'A' |
使用 type
无法进行类型扩展,因此
对外 API 尽量用
interface
,方便用户进行类型扩展;对内 API 尽量用type
,防止代码分散
例如,当你设计一个库或框架的公共 API 时,可以使用接口来定义输入和输出的数据结构,以提供明确的类型信息给用户,并允许用户按照自己的需求扩展接口。
而当你在代码内部定义一些仅在局部范围内使用的类型时,使用类型别名可以让代码更加集中和易于维护。它可以将类型定义与具体的实现逻辑分离开来,使代码更加模块化。
下面是一个扩展 interface
的实例:
扩展 axios
1 | import { AxiosRequestConfig } from 'axios'; |
扩展 string
1 | declare global { |
区别四
interface
使用 extends
来实现继承,而 type
只能用 &
来模拟继承
1 | interface A { |
void
1 | type Fn = () => void; |