# typescript(二)-- 基础类型

# 开始

ts中基础类型有如下几种:boolean / number / string / object / 数组 / 元组 / 枚举 / any / undefined / null / void / never, 下面我们一一举例学习:

# 基础类型

# 字面量

介绍类型前,有一个前置知识点就是字面量, 字面量的意思就是直接声明, 而非new关键词实例化出来的数据:

// 字面量
const n:number = 123;
const s:string = '456';
const o:object = {a:1,b:'2'};
// 非字面量
const n:Number = new Number(123);
const s:String = new String('456');
const o:Object = new Object({a:1,b:'2'});

通过上面的例子, 大家应该看明白为什么ts中有些类型的开头字母是小写的了吧. 这是因为ts中用小写字母开头的类型代表字面量, 大写的是用来表示通过new实例化的数据.

# boolean

布尔类型, 取值只有true / false

const IS_MOBILE:boolean = true;
const IS_TABLE:boolean = false;

#### number **数字类型**, 整数/小数都包括, 同时支持2/8/10/16进制**字面量**. ```typescript let decLiteral: number = 6; let hexLiteral: number = 0xf00d; let binaryLiteral: number = 0b1010; let octalLiteral: number = 0o744; ```
#### string **字符串类型** ```typescript let s1:string = 'hello world!'; let s2:string = 'hello ${name}`; ```
#### 数组 数组有2种表示方式:
**第1种**, 通过在**指定类型**后面增加`[]`, 表示该数组内的元素都是该**指定类型**: ```typescript let numbers:number[] = [1,2,3,4,5]; // number|string代表联合类型, 下面的高级类型中会讲 let numbers:(number|string)[] = [1,2,3,4,'5']; ``` **第2种**, 通过泛型表示, `Array<元素类型>`, **泛型**会在后面讲解, 先做了解即可: ```typescript let numbers:Array = [1,2,3,4,5]; ```
#### 元组(Tuple) **元组类型**表示一个已知**元素数量**和**类型**的**数组**, 各元素的类型不必相同: ```typescript let list1:[number, string] = [1, '2', 3]; // 错误, 数量不对, 元组中只声明有2个元素 let list2:[number, string] = [1, 2]; // 错误, 第二个元素类型不对, 应该是字符串'2' let list3:[number, string] = ['1', 2]; // 错误, 2个元素的类型颠倒了 let list4:[number, string] = [1, '2']; // 正确 ```

# 枚举(enum)

枚举是ts中有而js中没有的类型, 编译后会被转化成对象, 默认元素的值从1开始, 如下面的Color.Red的值为1, 以此类推Color.Green为2, Color.Blue为3:

enum Color {Red, Green, Blue}
// 等价
enum Color {Red=1, Green=2, Blue=3}

当然也可以自己手动赋值:

enum Color {Red=1, Green=2, Blue=4}

并且我们可以反向通过值得到他的键值:

enum Color {Red=1, Green=2, Blue=4}
Color[2] === 'Green' // true

看下编译成js后的枚举代码, 你就明白为什么可以反向得到键值:

var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Green"] = 1] = "Green";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));
// Color的值为: {0: "Red", 1: "Green", 2: "Blue", Red: 0, Green: 1, Blue: 2}

# any(任意类型)

any代表任意类型, 也就是说, 如果你不清楚变量是什么类型, 就可以用any进行标记, 比如引入一些比较老的js库, 没有声明类型, 使用的时候就可以标记为any类型, 这样ts就不会提示错误了. 当然不能所有的地方都用any, 那样ts就没有使用的意义了.

let obj:any = {};
// ts自己推导不出forEach中给obj增加了'a'和'b'字段.
['a', 'b'].forEach(letter=>{
    obj[letter] = letter;
});
// 但是因为标记了any, 所以ts认为a可能存在
obj.a = 123

# void

void的意义和any相反, 表示不是任何类型, 一般出现在函数中, 用来标记函数没有返回值:

function abc(n:number):void{
    console.log(n);
}

void类型对应2个值, 一个是undefined,一个null:

const n1:void = undefined;
const n2:void = null;

# null 和 undefined

默认情况下null和undefined是所有类型的子类型, 比如:

const n1:null = 123;
const n2:undefined = '123';

注意: 这是因为默认情况下的编译选项strictNullChecks为false, 但是为了避免一些奇怪的问题出现, 我还是建议大家设置为true(编译选项设置的内容, 会在后面的课程讲解), 请用精准的类型去标注.
如果一个变量的值确实需要是null或者undefined, 可以像下面这么用, ts会自动根据if/else推导出正确类型:

// 这是"联合类型", 在"高级类型"中会有详细介绍, 表示n可能是undefined也可能是number
let num: undefined|number;
if(Math.random()>0.5) num = 1;
if(undefined !== num) {
    num++;
}

# never

never表示不可达, 用文字还真不好描述, 主要使用在throw的情况下:

function error():never{
    throw '错了!';
}

# object

object表示非原始类型, 也就是除numberssbooleansymbolnullundefined之外的类型:

let o1:object = [];
let o2:object = {a:1,b:2};

但是, 我们实际上基本不用object类型的, 因为他标注的非常不具体, 一般都用接口来标注更具体的对象类型, 请继续看下面的接口的内容.

# 参考

  1. 为vue3学点typescript, 基础类型和入门高级类型 (opens new window)