空值void 及(与Null 和 Undefined的区别)

JavaScript 没有空值(Void)的概念,在 TS中,用 void 表示没有任何返回值的函数:

function alertName(): void {
    alert('My name is Tom');
}

然而声明一个 void 类型的变量没什么用,因为只能将其赋值为 undefined 和 null:

let unusable: void = undefined;

Null 和 Undefined

let u: undefined = undefined;
let n: null = null;

区别:undefined 和 null 是所有类型的子类型。也就是说 undefined 类型的变量,可以赋值给所有类型的变量,包括 void 类型:

let num: number = undefined;

let u: undefined;
let str: string = u;
let vo: void= u;

// 编译通过

而 void 类型的变量不能赋值给其他类型的变量,只能赋值给 void 类型:

let u: void;
let num: number = u;  // Type 'void' is not assignable to type 'number'.
let vo: void = u;     // 编译通过

任意值Any

  1. 任意值(Any)用来表示允许赋值为任意类型。一个普通类型,在赋值过程中是不被允许改变类型的,any 类型,允许被赋值为任意类型。
let str: string = 'abc';
str = 123;
 
// Type 'number' is not assignable to type 'string'.
  
// -----------------------------------------------------------------
  
let str: any = 'abc';
str = 123;
  
// 编译通过
  1. 任意值可以访问任意属性和方法:
let anyThing: any = 'hello';
   
anyThing.setName('Jerry');
anyThing.setName('Jerry').sayHello();
anyThing.myName.setFirstName('Cat');
   
console.log(anyThing.myName);
console.log(anyThing.myName.firstName);
   
// 编译通过
  1. 未声明类型的变量:如果变量在声明时,未指定类型,那么会被识别为任意值类型:
let something;
something = 'seven';
something = 7;

// 等价于
   
let something: any;
something = 'seven';
something = 7;  

元组类型

元组最重要的特性是可以限制数组元素的个数类型,可以通过数组的方法进行新增。只能新增已经存在的类型。

let tuple: [name: string, age: number, male: boolean] = ["yya", 18, false];
let username = tuple[3]; // 此时添加新元素,但是取不到 会抛异常

console.log(tuple[3]); // error 长度为 "3" 的元组类型 "[string, number, boolean]" 在索引 "3" 处没有元素。

枚举类型

自带类型的对象, 枚举的值如果没有赋值,默认从 0 开始递增. 并且只能在值为数字的情况下反举。
作用:代码中常量、状态码 、接口的定义、权限、标示位等可以采用枚举类型,提示友好,使用方便。

enum USER_ROLE { //
  USER = "a",
  ADMIN = 10,
  SUPER_ADMIN,
}
console.log(USER_ROLE.USER);

上述枚举 ts 代码,编译为 js,生成一个对象,并实现反举(值为数字时):

var USER_ROLE;
(function (USER_ROLE) {
  USER_ROLE["USER"] = "a";
  USER_ROLE[(USER_ROLE["ADMIN"] = 10)] = "ADMIN";
  USER_ROLE[(USER_ROLE["SUPER_ADMIN"] = 11)] = "SUPER_ADMIN";
})(USER_ROLE || (USER_ROLE = {}));

console.log(USER_ROLE.USER);

常量枚举

区别:常量枚举不能反举,一般用不到反举的情况下,都采用常量枚举,编译后的结果,不会生成对象,而是直接将值取出来。
写法上有些许不同,就是使用的const 关键字进行常量的声明

const enum USER_ROLE { //
  USER = "a",
  ADMIN = 10,
  SUPER_ADMIN,
}
console.log(USER_ROLE.USER);

编译为 js 代码,并不会生成一个对象:

console.log("a" /* USER_ROLE.USER */);

never 类型

任何类型的子类型,never 代表不会出现的值。不能把其他类型赋值给 never

1. 函数无法到达终点

// 循环不停止的情况
function whileTrue(): never {
  while (true) {}
}

// 或者抛出异常的情况
function throwError(): never {
  throw new Error();
}

function test() {
  throwError();
  let a = 1; // 此行代码会置灰,并提示 检测到无法访问的代码。
}

2.通常校验逻辑的完整性,可以利用 never 类型

function getResult(param: string | number | boolean) {
  if (typeof param === "string") {
    return param.split("");
  } else if (typeof param == "number") {
    return param.toString().split("");
  } else if (typeof param == "boolean") {
    return param.toString().split("");
  } else {
    // 如果达不到never 则可以正常的运行
    // 如果参数类型判断缺失boolean,则会抛出异常,不能将类型“boolean”分配给类型“never”。
    let n: never = param;
  }
}

Symbol 类型

Symbol 表示独一无二

const s1 = Symbol("key");
const s2 = Symbol("key");
console.log(s1 == s2); // false

BigInt 类型

当数值类型超出安全数值时,使用 bigInt 类型

const num1 = Number.MAX_SAFE_INTEGER + 1;
const num2 = Number.MAX_SAFE_INTEGER + 2;
console.log(num1 == num2); // true

let max: bigint = BigInt(Number.MAX_SAFE_INTEGER);
console.log(max + BigInt(1) === max + BigInt(2)); // false