新的类型
TS
中除了 JS
原本的类型外,还增加了几个新类型,接下来,我们来瞧瞧都有谁。👀
Any
any
类型表示没有任何限制,它可以赋值给任何类型,任何类型也可以赋值给它。
它通常被称为 Top type any,即顶层类型。一旦设置为 any
类型,TS
实际上会关闭类型检查,它会认为开发者想自己来处理这些代码。
javascript
let articleName: any;
articleName = '橙某人';
articleName = 18;
articleName = true;
一般建议尽可能少使用 any
类型。🔞
Unknown
unknown
被视为严格版的 any
,任何类型都能赋值给 unknown
类型,但是反之不行,它只能赋值给 any
类型和本身。
javascript
let articleName: unknown;
articleName = '橙某人';
articleName = 18;
articleName = true;
let str: string;
let num: number;
let bool: boolean;
str = articleName; // ❌
num = articleName; // ❌
bool = articleName; // ❌
unkown
也属于顶层类型。
Never
never
类型表示空类型,或者说是指不存在的类型或者状态。
TS
引入了 "空类型" 的概念,即该类型为空,不包含任何值,也不可能存在这样的值。
它能赋值给任意其他类型,反之不行。
javascript
let nev = ():never => {
throw new Error('Error');
};
let str: string;
let num: number;
let bool: boolean;
str = nev();
num = nev();
bool = nev();
nev = str; // ❌
nev = num; // ❌
nev = bool; // ❌
它一般会被应用在函数中,表示函数出现异常的情况,如函数运行抛出错误、函数出现死循环情况、或者是判断分支溢出等等。
Void
void
类型表示没有返回值,一般用来描述函数、Promise
等的返回值类型。
javascript
const fn = ():void => {};
const promise = new Promise<void>(resolve => resolve());
promise.then(res => {
// res: void
});
void
是 undefined
的子类型。
javascript
let voi: void;
voi = undefined;
voi = void 1;
void
其实和 undefined
是一样的,但是为什么还需要它呢?这还是因为 undefined
在 JS
中是允许被随意覆盖的,而 void
才是真正意义上的 undefined
。
Tuple - 元组
元组(tuple)可以看成是数组(Array)类型的一个特殊扩展,它精确地知道它包含了多少个元素,以及它在特定位置包含哪些类型。
🔉"一一对应,不多不少"
javascript
let arr: [string, number, boolean] = ['橙某人', 18, true];
let arr1: [string, number, boolean] = ['橙某人', 18]; // ❌
let arr2: [string, number, boolean] = ['橙某人', 18, true, undefined]; // ❌
无法自动推断
使用元组时,必须明确给出类型声明,否则 TS
会把它自动推断为数组类型。
javascript
let arr = ['橙某人', 18, true]; // (string | number | boolean)[]
可选成员
元组成员的类型也能变成可选(?
)的,但它必须被放在最后一项。
javascript
let arr: [string, number, c?: boolean] = ['橙某人', 18];
let arr1: [string, c?: boolean, number] = ['橙某人', undefined, 18]; // ❌
扩展运算符(...)
元组中也可以使用扩展运算符(...
),并且它能在元组中的任意位置,但是它后面只能是数组或者元组。
javascript
let arr1: [string, ...number[]] = ['橙某人', 18];
let arr2: [...number[], string] = [18, '橙某人'];
let arr3: [string, ...number[], boolean] = ['橙某人', 18, 20, true];
// 元组
let arr4: [string, ...[number, boolean], number] = ['橙某人', 18, true, 1];
Enum - 枚举
枚举(enum)是 TS
新增加一种数据结构,同时它也是一种类型。
枚举可以分类成三种形式:数字枚举、字符串枚举、混合枚举(不推荐)。
数字枚举
javascript
enum Color {
red = 0,
green = 1,
blue = 2,
}
console.log(Color.red); // 0
console.log(Color.green); // 1
console.log(Color.blue); // 2
默认情况下,数字枚举成员会从0开始自动增长。
javascript
enum Color {
red,
green,
blue,
}
console.log(Color.red); // 0
console.log(Color.green); // 1
console.log(Color.blue); // 2
并且是相对上一个数字成员增长。
javascript
enum Color {
red,
green = 3,
blue,
}
console.log(Color.red); // 0
console.log(Color.green); // 3
console.log(Color.blue); // 4
当然,你可能会想到这种情况:
javascript
enum Color {
red,
green = 'g',
blue,
}
这种情况是不被允许的,它要求 Color.blue
必须初始化。
字符串枚举
字符串枚举是在 TS
的 2.4
版本才被引入的,字符串枚举的所有成员值,都必须显式设置。
javascript
enum Color {
red = 'r',
green = 'g',
blue = 'b'
}
同名自动合并
多个同名的枚举结构会自动进行合并,并且在只有第一个枚举声明可以省略其初始化表达式。
javascript
enum Color {
red,
}
enum Color {
green = 1, // 必须初始化
}
enum Color {
blue = 2, // 必须初始化
}
多个同名的枚举进行合并的时候,不能有同名的成员。
javascript
enum Color {
red,
}
enum Color {
green = 1,
}
enum Color {
red, // ❌
}
反向映射
什么是反向映射呢?这是数字枚举成员 才有的一种特性,其实就是双向能相互访问(key <=> value
)。
javascript
enum Color {
red,
green,
blue
}
console.log(Color.red); // 0
console.log(Color[0]); // red
可以来看看它是如何来实现的,执行 tsc
命令编译成 ES5
代码。
javascript
var Color;
(function (Color) {
Color[Color["red"] = 0] = "red";
Color[Color["green"] = 1] = "green";
Color[Color["blue"] = 2] = "blue";
})(Color || (Color = {}));
/* Color:
{
"red": 0,
"green": 1,
"blue": 2,
"0": "red",
"1": 'green",
"2": "blue"
}
*/
再来看看字符串枚举成员的编译结果:
javascript
enum Color {
red = 'r',
green = 'g',
blue = 2
}
var Color;
(function (Color) {
Color["red"] = "r";
Color["green"] = "g";
Color[Color["blue"] = 2] = "blue";
})(Color || (Color = {}));
/* Color:
{
"2": "blue",
"red": "r",
"green": "g",
"blue": 2
}
*/
作为类型使用
javascript
enum Color {
red,
green,
blue,
}
let color1: Color = 0;
let color2: Color.red = Color.red;
let color3: Color.red = Color.green; // ❌
枚举不能修改-const
枚举有点像"常量"的意思,它的成员值都是只读,不允许再修改。
javascript
enum Color {
red,
green,
blue,
}
Color.red = 3; // ❌
enum
关键字前面还可以加上 const
修饰符。
javascript
const enum Color {
red,
green,
blue,
}
const
修饰符能更加明确表达枚举不可被修改的特性,并且它们在编译之后还有所不同。
javascript
enum Color {
red,
green,
blue,
}
let red = Color.red;
let green = Color.green;
let blue = Color.blue;
/* 编译后:
var Color;
(function (Color) {
Color[Color["red"] = 0] = "red";
Color[Color["green"] = 1] = "green";
Color[Color["blue"] = 2] = "blue";
})(Color || (Color = {}));
var red = Color.red;
var green = Color.green;
var blue = Color.blue;
*/
javascript
const enum Color {
red,
green,
blue,
}
let red = Color.red;
let green = Color.green;
let blue = Color.blue;
/* 编译后:
var red = 0;
var green = 1;
var blue = 2;
*/
加上 const
修饰符的枚举,其枚举成员会被直接替换成对应的值,这在一定程度上能起到提高性能的作用。
🍊关于枚举出现的作用或意义?
枚举的作用能替代魔法数字、提高代码的可读性和扩展性、增加编辑器的代码提示和自动补全。
至此,本篇文章就写完啦,撒花撒花。
希望本文对你有所帮助,如有任何疑问,期待你的留言哦。
老样子,点赞+评论=你会了,收藏=你精通了。