本篇主要介绍了TS的一些基础知识。
前言
『前期回顾』
基础知识
TS中的类型层次
Unknown
- 全集(Top Type)
Never
- 空集(Bottom Type)
知识点
- 下层类型的值可以赋给上层类型的变/常量
- unknown类型的变/常量可以指向任何类型的值。
- 不存在never类型的变量( never是空集)
Top/Bottom Type对比
不同语言的Top Type和Bottom Type对比
any
1、any比较特殊,其实它既是Top Type又是Bottom Type
- 也就是说: any类型的变量/常量+任何其他类型变量/常量可以互相赋值
- 但any是类型不安全的、无语言服务的,所以应该尽量避免使用
2、any具有传染性
- 它会使它所触及的地方变得不安全(Type Unsafe),所以TS在3.0引入了类型安全的unknown类型作为Top Type
3、any会隐藏bug
- 因为没有类型信息,即便错误使用,也没有任何报错。
如以下示例:字符串birthDate没有getTime()方法,但不会报错。
4、any会隐藏代码设计细节:丢失了对数据类型的设计
因为any有以上各种问题,所以建议在tsconfig中开启strict模式或禁止隐式any
知识点:
开启noImplicityAny尽量避免使用any
unknown
- unknown类型必须显示注解,TS不会把任何值推导为unknown
- unknown类型只能进行等于和不等于比较
- 有类型收窄后才能进行相应运算或函数调用
如果无法预知类型,不要用any,用unknown,收窄类型后再使用
布尔类型(boolean)
布尔类型只有两个元素: true和false
-
let,var变量会被拓宽成boolean类型,const常量就是对应字面量类型
-
有一点值得注意的是 ,true和false的联合类型,会被反推回boolean类型
number类型
number包括:整数、浮点数、+Infinity(正负无穷 ), NaN
bigint类型
- bigint是新引入的类型,可以表示任意大小的整数,number范围[- ( 2^53-1 ),2^53-1]
- bigint字面量是在数字后面加小写"n" 。bigint支持 加+,减,乘*,除/,求余%,幂**
如果想用bigint类型,配置的【compilerOptions>target】要选择大于等于es2020
字符串类型(string)
字符串字面量联合常用区分数据类型
符号类型(symbol)
symbol是ES2015引|入的新的语言特性
-
let、var声明的变量推导成symbol类型
-
unique symbol必须是const常量
-
const常量推导成unique symbol,也可以显示注解成unique symbol
-
unique symbol不是一个类型,而是一组类型。比如unique symbol b1和unique symbol b1x是两个类型
unique symbol怎么理解?
对比
字符串字面量类型 VS unique symbol
- 与其他字面量类型不同, unique symbol类型无法直接引用,必须通过"typeof常量”的形式引用。
- 字符串字面量类型可以直接用对应的字符串来表示
知识点
-
将unique symbol赋值给另一个const时,类型会拓宽为symbol
-
如果不希望拓宽,需要显示注解为对应常量的typeof
-
Symbol的第一个参数是描述 ,不是符号名,也不是符号ID。每次调用Symbo都会返回一个全新的符号,即便描述相同。
-
Symbol.for在内部维护了一个字典,如果之前没有创建过对应描述的符号,就返回一个新的符号,如果创建过,就返回已创建的符号。
对象类型(Object)
通过以下两点来理解以下【对象类型】
- 定义对象和定义对象类型;
- 获取对象keys和获取对象类型keys
不清楚【值空间】【类型空间】【Equal】的,可以看看上一篇👉现在去
数组类型(Array)
数组有两种注解方式:
T[]
Array<T>
接口泛型
知识点:
-
const数组不会收窄因为收窄就变成tuple类型了
-
TS无法推断空数组的类型,只能推断为any[]
-
但是,当离开作用域时TS可以分析代码,推断出数组的类型
元组(Tuple)
元组( Tuples )是数组的子类型。元组各索引位上的元素类型是确定的。
知识点:
- 因为元组的创建方法和数组是一样的,所以元组必须显示注解。
[...string[]]等价于string[] ,但[string, ...string[]]不等价于string[],前者至少包含一个元素
枚举(Enum)
枚举本质上是一种映射。会在值空间产生一个包含该映射的对象。
打印结果
可以看到
-
未显式赋值的枚举值自动从0自增赋值,存在双向映射(如上面的Chinese)
-
显示赋值为整数的枚举,存在双向映射(如上面的Japanese)
-
显式赋值字符串的枚举不存在反向映射,只有单项映射(如上面的Korean)
枚举的合并
枚举可以拆分成多段,还可以与同名namespace合并
-
namespace可以和enum合并
-
enum可以拆分多段后合并
常量枚举
- 常量枚举不会在值空间创建变量。
- 所有引用常量枚举的地方都被替换为对应的值
(但是可以通过【compilerOptions>preserveConstEnum】编译器选项来控制)
-
常量枚举没有双向映射
-
常量枚举仍然支持分多段;但是由于常量枚举不生成变量。所以不支持与namespace的合并
-
并且TS会输出常量对应的key ,方便调试
可以对比以下enum与constenum生成的JS代码
null,undefined,void,never
最后来看看这四个比较容易混淆的四个类型
JS中
- Undefined = {undefiend} ,应该表示尚未定义但是,实际上表示已声明,未赋值
- Null = {nul} ,表示已声明,值为nul或值为空
TS中
-
void类型:函数没有显式返回值
-
never类型:函数无法返回
在JS
void是个一元操作符:它执行后面的表达值,然后无条件返回undefined
为什么要有这样一个操作符?
在ES1.3之前, undefined是无法直接访问的!只能通过void(0)这种形式得到。ES1.3将undefined添加到了global object上之后才可以访问。
结语
本节课的讲师:字节前端—王韦华
如以上有错误的地方,请在评论区中指出!
我们的征途是星辰大海!🚀