# typescript(一) - 数据类型

# typescript初体验

首先我们需要全局安装ts



npm i typescript -g

全局安装完之后我们新建一个hello.ts文件




// hello.ts
let name:string = 'chenying'

然后我们在cmd输入tsc hello.ts 来编译这个文件, 我们会发现产生了一个hello.js文件, 就是我们ts编译后的js代码




// hello.js
var name = 'chenying'

但是如果我们每次都用tsc xxx这种方式来编译的话太过于麻烦, 我们可以去配置脚本或者用vscode自带的功能来完成

首先我们需要生成ts的配置文件 -> tsc --init

然后我们在vscode找到 终端 -> 运行任务 -> tsc: 监视 就可以了

# 数据类型

我们先来学习一下ts的数据类型

# 布尔类型(boolean)



let isBoy: boolean = true

# 数字类型(number)



let age: number = 22

# 字符串类型(string)



let name: string = 'chenying'

# 数组类型(array)

数组类型的定义方式有两种




// 1
let hobbies:string[] = ['vue', 'react', 'egg']

通过 string[] 的 方式定义一个字符串数组, 数组里面的元素只能是字符串, 否则报错




// 2
let hobbies1:Array<string> = ['vue', 'react', 'egg']

通过 Array<string> 的 方式定义一个字符串数组, 数组里面的元素只能是字符串, 否则报错

# 元组类型(tuple)

元祖类型其实和数组差不多, 它是表示一个已知数量和类型的数组



let tuple:[number, string] = [1, 'chenying']

表示数组的数量只能为2, 并且每一项对应的类型要一致

我们来看一下数组和元祖的区别

数组:

  • 每一项都是同一种类型
  • 没有长度限制
  • 用于表示一个列表

元祖:

  • 每一项可以是不同的类型
  • 有预定义的长度
  • 用于表示一个固定的结构

# 枚举类型(enum)

枚举类型表示事先考虑某一个变量的所有的可能的值, 如我们定义一个变量weekend, 我们事先是知道它的值为Saturday 或者Sunday。枚举类型有两种, 分别是普通枚举和常数枚举

# 普通枚举




 


enum weekend {
    Saturday,
    Sunday,
}
console.log(weekend) // { '0': 'Saturday', '1': 'Sunday', Saturday: 0, Sunday: 1 }

# 常数枚举




 



const enum color {
    Red,
    Yellow,
}
console.log(color)// color is not defined 因为color在编译阶段就已经被删除了
console.log(color.Red)// 0 

普通枚举和常数枚举的区别是常数枚举会在编译的阶段被删除, 所以我们访问不到color, 但是我们可以访问到color.Red

# 任意类型(any)

any名声在外, 很多人说typescript又叫anyscript

其中any表示可以赋值给任意类型, 一般我们在使用第三方库而且库没有提供类型文件的时候可以用any, 或者数据真的复杂到我们很难去写出它的类型的时候可以用any




 

let name:any = 'chenying'
name = 1
name = true
name = '112313'

# null 和 undefined

在ts中, nullundefined 是其它类型的子类型, 这句话什么意思呢, 我们看下代码




 

let x: number;
x = 1;
x = undefined;    
x = null;   

我们在运行这段代码之前需要改一下tsconfig.json中的strictNullChecks置为false, 因为在ts中,nullundefined 是其它类型的子类型, 所以我们无法正确的判断出它们是否使用正确, 所以引入了strictNullChecks ,当strictNullCheckstrue的时候表示可以检测到, 所以这里我们需要把它置为false

在代码中我们可以发现, number型的x可以被赋值为nullundefined, 这就证明了 nullundefined 是其它类型的子类型

# void 类型

void表示没有任何类型, 一般用于校验函数返回值




 

function say():void {
    // return 1123 // 不能将类型“1123”分配给类型“void”
    console.log('hello ts')
}

# never 类型

never是其它类型(包括nullundefined)的子类型,代表不会出现的值

一般当我们的函数永远不会正常结束的时候需要返回never




 





// 抛出错误, 没有正常结束
function error(message: string): never {
    throw new Error(message);
}
// 死循环
function error(message: string): never {
    while (true) {}
}

# 类型推论

类型推论的意思是当我们定义的时候没有赋值, 则会自动被推论为any类型




 

let name
name = 1
name = true
name = 'string'

# 包装对象(Wrapper Object)

包装对象的概念其实和js是一样的, 我们知道js中所有的原始数据类型都没有属性, 但是为什么一个字符串可以调用toUpperCase方法呢, 其实是在调用toUpperCase执行, js很快的进行了一次包装对象, 对应java的装箱拆箱, ts也是如此




 

let name = 'chenying'
console.log(name.toUpperCase())
// 实际上在调用toUpperCase之前进行了对象的包装
console.log((new String('chenying')).toUpperCase());

# 联合类型

联合类型表示取值可以是定义的多种类型中的一种




 

let name:string | number
name = 'chenying'
name = 123
name = true //报错 因为name只能为 string 或者 number

# 类型断言

类型断言可以将一个联合类型的变量,指定为一个更加具体的类型,但是我们不能断言成联合类型中不存在的类型




 

let name: string | number
console.log((name as string).length)
console.log((name as number).toFixed(2))
console.log((name as boolean)) // 报错