TypeScript支持的数据类型(一)

说明

TypeScript 做为JavaScript 的超集,对于JavaScript中的类型完全支持,除了JavaScript中的类型之外,TS自身也提供了一些数据类型。

在TS中,数据类型的整体结构如下:

  • 最顶级的类型,any 与 unknown
  • 特殊的 Object ,它也包含了所有的类型,但和 Top Type 比还是差了一层
  • String、Boolean、Number 这些装箱类型
  • 原始类型与对象类型
  • 字面量类型,即更精确的原始类型与对象类型,需要注意的是 null 和 undefined 并不是字面量类型的子类型
  • 最底层的 never

顶层类型

顶层类型主要包括anyunknown

any类型在ts中属于Top Type, 如果一个变量被标注为any类型,那么这个变量在进行赋值时,可以接受任意类型的数据,同时,any类型的数据也可以赋值给任意类型的变量。

// any
let val: any

val = true
val = 100
val = null
val = undefined

let val2: string = val
let val3: number = val
let val4: null = val
let val5: undefined = val
let val6: boolean = val

需要注意的是,any类型的特殊性导致我们经常较为随意的使用它,哪里出了问题,就随便any一下,用的多了,也就变成了AnyScript。

unknown类型同样属于顶层类型,一个被标注为unknown类型的变量可以被赋值为任意其他类型,但是unknown类型的数据只能赋值给any和unknown类型的变量。

// unknown
let val1: unknown = true
val1 = 100
val1 = undefined
val1 = null

let val2: unknown = val1
let val3: any = val1

如果想要对unknown类型的数据进行访问,需要通过类型断言。

例如:

let unknownVar: unknown;

(unknownVar as { foo: () => {} }).foo();

Object 类型

Object在JS中,位于原型链的顶端,所有的原始类型和对象类型都指向Object。

Object类型在TS中,和顶层的any类似,包含了所有类型的信息,但是却没有在top type中,位置仅次于Top Type。

// 对于 undefined、null、void 0 ,需要关闭 strictNullChecks
const tmp1: Object = undefined;
const tmp2: Object = null;
const tmp3: Object = void 0;

const tmp4: Object = 'hello,world';
const tmp5: Object = 100;
const tmp6: Object = { name: 'root' };
const tmp7: Object = () => {};
const tmp8: Object = [];

装箱类型

在TS中,Object、Boolean、Number、String、Symbol这些类型是TS中的装箱类型(Boxed Types)。每一个装箱类型都包括对应的拆箱类型(Unboxed Types)和一些超出预期的值。

这里以装箱类型Number为例,包括拆箱类型number, 以及超预期值undefined、null、void等(在strictNullChecks为false的情况下)。

大多数情况下,都不应该直接使用装箱类型。

这里需要关注一下object类型,object类型的引入就是为了解决对 Object 类型的错误使用,它代表所有非原始类型的类型,即数组、对象与函数类型这些:

const tmp17: object = undefined;
const tmp18: object = null;
const tmp19: object = void 0;

const tmp20: object = 'root';  // X 不成立,值为原始类型
const tmp21: object = 100; // X 不成立,值为原始类型

const tmp22: object = { name: 'root' };
const tmp23: object = () => {};
const tmp24: object = [];

同时,我们也要避免使用{}对象直接量这种形式,{}意味着任何非 null / undefined 的值,从这个层面上看,使用它和使用 any 差不多。

当设置一个变量的时候,如果已经确定不是原始类型,可以使用object。除了设置为object,还可以使用Record<string, unknown>或者Record<string, any>表示对象,unknown[]或者any[]表示数组,(...args: any[]) => any 表示函数。

字面量类型

字面量类型是所有拆箱类型的子类型,属于比原始类型更加精确的数据类型,属于原始类型的子类型。

字面量类型主要包括字符串字面量、数字字面量类型、布尔字面量类型和对象字面量类型。

当一个常量被赋值为字面量的值时,这个常量的类型就为字面量类型。

image

单独使用字面量类型比较少见,较为常见的是联合类型和字面量类型结合使用。

image

never

在TS中,never类型表示什么都没有, 甚至不包括空的类型。never类型本身并不会携带任何信息,所以在TS中属于Bottom Type。和null 和 undefined 一样,属于其他类型的子类型,但只有 never 类型的变量能够赋值给另一个 never 类型变量。

一般来说,它主要被类型检查所使用,有时,never类型常用来当做一个抛出错误的函数返回值。

例如:
image

一个返回值类型为 never 的函数被调用,那么下方的代码都会被视为无效的代码(即无法执行到):

function justThrow(): never {
  throw new Error()
}

function foo (input:number){
  if(input > 1){
    justThrow();
    // 等同于 return 语句后的代码,即 Dead Code
    const name = "root";
  }
}
posted @ 2023-01-08 22:42  Des李白  阅读(259)  评论(0编辑  收藏  举报