前言

本文主要记录下 TypeScript 中的基本类型,日常学习总结篇。 

一、布尔值(boolean)

TypeScript 的布尔值和 JavaScript 一样有两个值:true、false。示例如下:

let isDone: boolean = true

// 也可以是一个计算之后结果为布尔值的表达式
let isDone: boolean = !0

注意:使用构造函数 Boolean 创造的对象不是布尔值。

let isDone: boolean = new Boolean(1)

// Type 'Boolean' is not assignable to type 'boolean'.
//   'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible.

// 不能将类型 "Boolean" 分配给类型 "boolean"。
// "boolean" 是基元,但 "Boolean" 是包装器对象。如可能首选使用 "boolean"。

在 TypeScript 中,boolean 是 JavaScript 中的基本类型,而 Boolean 是 JavaScript 中的构造函数。

二、数值(number)

和 JavaScript 一样,TypeScript 的所有数字都是用浮点数表示,支持二进制、八进制、十进制以及十六进制的表示方式。示例如下:

let decimal: number = 6; // 十进制
let hex: number = 0xf00d; // 十六进制,以0x开头,0x后面数值为十六进制
let binary: number = 0b1010; // 二进制,以0b开头,0b后面数值为二进制
let octal: number = 0o744; // 八进制,以0o开头,0o后面为八进制
let notANumber: number = NaN;
let infinityNumber: number = Infinity;

三、字符串(string)

和 JavaScript 一样,可以使用双引号 ( " ) 或者单引号 ( ' )

let name: string = "jenny";
let age: number = 18;

同时 TypeScript 支持 ES6 的模版字符串。这种字符串是被反引号 ( ` ) 包裹,并且以 ${ expr }这种形式嵌入表达式。示例如下:

let sentence: string = `你好,我是${name},

我今年${age}岁了`;

四、数组(array)

TypeScript 像 JavaScript 一样可以操作数组元素。在 TypeScript 中有两种定义数组的方式。

1⃣️、可以在元素类型后面加上 [ ]

const list_1: number[] = [1, 2, 3]
const list_2: string[] = ['a', 'b']
const list_3: boolean[] = [true, false]

2⃣️、使用数组泛型,Array<元素类型>。示例如下:

const list_1: Array<number> = [1, 2, 3]
const list_2: Array<string> = ['a', 'b']
const list_3: Array<boolean> = [true, false]

五、元组(tuple)

元组可以看做是数组的扩展,它表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同。示例如下:

let arr: [number, string, boolean]
arr = [1, 'a', true] // 正确
arr = ['a', 2, 'c'] // 报错:不能将类型“string”分配给“number"。不能将类型“number”分配给“string"。不能将类型“string”分配给“boolean"。
arr = [1, 'a'] // 报错:不能将类型“[number, string]”分配给类型“[number, string, boolean]”。源具有 2 个元素,但目标需要 3 个。

访问元组元素时,TypeScript 也会对元素做类型检查。例如一个元素是字符串类型,那么它只能使用字符串方法,如果使用别的类型方法,就会报错。

TypeScript 也会对元组做越界判断,超出规定个数的元素被称作越界元素,元素赋值必须类型和个数都对应,不能超出定义的元素个数。

六、枚举(enum)

枚举类型用于定义数值集合。简单来讲是给一组数值赋予名字,对开发者比较友好。示例如下:

enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat }

默认情况下,枚举成员会被赋值为从 0 开始递增的数字,同时也会对枚举值到枚举名进行反向映射。示例如下:

enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat }

console.log(Days["Sun"] === 0); // true
console.log(Days["Tue"] === 2); // true
console.log(Days["Sat"] === 6); // true

console.log(Days[1] === "Mon"); // true
console.log(Days[2] === "Tue"); // true

也可以给枚举成员手动赋值。示例如下:

enum Days { Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat }

console.log(Days["Sun"] === 7); // true
console.log(Days["Mon"] === 1); // true
console.log(Days["Tue"] === 2); // true
console.log(Days["Sat"] === 6); // true

手动赋值也可以为字符串。示例如下:

enum Days { Sun = 'a', Mon, Tue, Wed, Thu, Fri, Sat } // 报错
// 如果枚举成员的上一位元素被赋值为 string 类型,那么当前的元素必须手动赋予初始值
// 如果枚举成员的上一位元素被赋值为 number 类型,那么下一位元素默认赋值为上一位的值 +1

七、object

object 表示非原始类型,也就是除 number、string、boolean、symbol、null 和 undefined 之外的类型。使用 object 类型,就可以更好的表示像 Object.create 这样的 API。示例如下:

declare function create(o: object | null): void

create({ prop: 0 });
create(null);

create(1); // 报错:类型“number”的参数不能赋给类型“object”的参数。
create("abc"); // 报错:类型“string”的参数不能赋给类型“object”的参数。
create(false); // 报错:类型“boolean”的参数不能赋给类型“object”的参数。

八、 any

any 表示任意类型,定义为 any 类型的变量会绕过 TypeScript 的静态类型检测。例如可以将一个值定义为 any 类型,也可以在定义数组类型时使用 any 来指定数组中的元素类型为任意类型。示例如下:

let value: any
value = 123
value = 'abc'
value = true

const arr: any[] = [1, 'a', false]

注意: 不要滥用 any 类型,如果代码中充满了 any,那 TypeScript 和 JavaSvript 就毫无区别了,所以要尽量避免使用 any,并且开启禁用隐式 any 的设置。

九、unknown

unknown 是 TypeScript 在 3.0 版本新增的类型,主要用来描述类型并不确定的变量。它看起来和 any 类型很像,但 unknown 相对于 any 更安全。示例如下:

let value: unknown;

value = 1
value = 'abc'
value = true

unknown 与 any 的主要区别是 unknown 类型会更加严格。在对 unknown 类型的值执行大多数操作之前,我们必须进行某种形式的检查,而在对 any 类型的值执行操作之前,我们不必进行任何检查。使用 unknown 时,需要注意以下几点:

  • 任何类型的值都可以赋值给 unknown 类型;
  • unknown 不可以赋值给其它类型,只能赋值给 unknown 和 any 类型;
  • 只能对 unknown 类型的值进行等或者不等操作,不能进行其它操作;
  • unknown 类型的值不能访问其属性、作为函数调用和作为类创建实例。 

十、void

void 类型与 any 类型相反,它表示没有任何类型。当一个函数没有返回值时,通常其返回值类型是 void。示例如下:

const clgTxt = (value: string): void => {
  console.log(value)
}

注意:void 类型的变量只能赋值为 null 和 undefined,其他类型不能赋值给 viod 类型的变量。 

十一、 never

never 类型表示的是那些永不存在的值的类型。例如:never 类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型;变量也可能是 never 类型,当它们被永不为真的类型保护所约束时。示例如下:

// 返回 never 的函数必须存在无法达到的终点
function error(message: string): never {
  throw new Error(message);
}

// 推断的返回值类型为 never
function fail() {
  return error("Something failed");
}

// 返回 never 的函数必须存在无法达到的终点
function infiniteLoop(): never {
  while (true) {
  }
}

never 类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是 never 的子类型或可以赋值给 never 类型(除了 never 本身之外)。即使 any 也不可以赋值给 never。 

十二、null 和 undefined

在 JavaScript 中,null 和 undefined 是两个基本数据类型。在 TypeScript 中,null 和 undefined 两者各自有自己的类型分别为 null 和 undefined。示例如下:

let n: null = null

let u: undefined = undefined

默认情况下,null 和 undefined 是所有类型的子类型。就是说可以把 null 和 undefined 赋值给 number 类型的变量。示例如下:

let num: number = null

当在 tsconfig.json 的 "compilerOptions" 里设置 "strictNullChecks": true 时,就是严格检查空值了,这时 null 和 undefined 只能赋值给它们自身或者 void 类型。