# 环境搭建

因为 TypeScript 是无法直接在浏览器上运行的,所以需要先将 Typescript 编译成 Javascript 代码后才能使用

# 安装 TS

全局安装 Typescript

npm install -g typescript

检查安装情况

tsc -v

# 手动编译

手动编译仅需在目录下 tsc 文件名.ts ,例如:

tsc index.ts

# vscode 自动编译

每次都要自行编译很麻烦,在 vscode 情况下我们可以使用监视任务让他自动编译。首先生成 ts 配置文件:

// 生成配置文件tsconfig.json
tsc --init

然后根据需要修改配置文件,常见的修改有设置输出 js 文件的目录、开启严格模式等。根据每项参数后面的注解按需修改配置

//tsconfig.json 内设置编译好的 js 文件输出的目录
"outDir":"./js" // 输出到当前文件夹下的 js 文件夹里面

最后启动监视任务,监视 tsconfig.json 文件

终端 -> 运行任务 -> 监视tsconfig.json

image-20220430102519183

# webpack 打包编译

下载依赖并配置使用即可

yarn add -D typescript  // 下载ts编译包
yarn add -D ts-loader   // 下载ts的loader

# 基础类型

TS 的基本数据类型和 JS 是一致的。

除了基本数据类型,TS 新增了 统一类型的数组元组枚举anyvoid 类型。

# 变量类型指定

我们可以像强类型语言一样指定变量的类型,仅需在后面 :指定类型 就可以完成类型检查

let num1:number = 10 // ok
let num2:number = 'a' // error
// 自动类型推断
let num3 = 10 // 根据初始赋值推断出变量类型为 number
num3 = 20 // ok
num3 = 'a' // error

# 函数返回值指定

指定函数的返回值类型

function fn(x:number,y:number):number{ // 指定函数返回值类型为 number
	return x + y;
}

# 数组

TS 的数组定义像 C/C++ 那样的强类型语言一样,指定数组内只能存同种类型的数据。可以在元素类型后面接上 [] ,表示由此类型元素组成的一个数组:

let numArr:number[] = [1,2,3] // 指定只能存数字类型的数据
let numArr:number[] = [1,'a','c'] // 能强行通过编译,但是会报错

或者使用泛型声明:

let numArr:Array<number> = [1,2,3]

# 元组

元组类型允许表示一个已知元素数量和类型的数组, 各元素的类型不必相同 。听起来像 javascript 原生的数组,但是并不一样。元组的限制很大,会固定数据的排列方式和数组大小。

let arr:[string,number] // 和 let arr = [] 不一样
arr = ['hello',10] // ok
arr = [10,'hello'] //error 报错
// 当访问一个已知索引的元素,能够得到正确的类型,会有智能提示.js 原生数组不具有
console.log(arr[0].substring(1)) // ok
console.log(arr[1].substring(1)) // error

# 枚举

枚举类型 enum 类似 C/C++ 里的枚举,能够修改枚举的值。默认枚举值是 1,后续枚举值依次递增 + 1 的

enum Color{
    red,
    green,
    yellow,
    blue
}
// 枚举值默认从 0 递增
console.log(Color.red) // 0
console.log(Color.green) // 1
console.log(Color.yellow) // 2
console.log(Color.blue) // 3

可以手动指定枚举值

enum Color{
    red = 100,
    green,
    yellow = 200,
    blue
}
// 手动指定枚举值后,后续枚举值会在此基础上 + 1 递增
console.log(Color.red) // 100
console.log(Color.green) // 101
console.log(Color.yellow) // 200
console.log(Color.blue) // 201

还可以利用类似索引的方式反过来取值

enum Color{
    red = 100,
    green,
    yellow = 200,
    blue
}
// 可以根据对应的枚举值反向取值
console.log(Color[100]) // red
console.log(Color[101]) // green
console.log(Color[200]) // yellow
console.log(Color[201]) // blue

# any

有时候,我们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,比如来自用户输入或第三方代码库。 这种情况下,我们不希望类型检查器对这些值进行检查而是直接让它们通过编译阶段的检查。 那么我们可以使用 any 类型来标记这些变量:

let a:any = 10
a = 20 // ok
a = 'abc' // ok

# void

某种程度上来说, void 类型像是与 any 类型相反,它 表示没有任何类型 。 当一个函数没有返回值时,你通常会见到其返回值类型是 void

/* 表示没有任何类型,一般用来说明函数的返回值不能是 undefined 和 null 之外的值 */
function fn(): void {
  console.log('fn()')
  // return undefined
  // return null
  // return 1 // error
}

# 联合类型

联合类型(Union Types)表示取值可以为多种类型中的一种

// 需求 1: 定义一个一个函数得到一个数字或字符串值的字符串形式值
function toString2(x: number | string) : string {
  return x.toString()
}
// 需求 2: 定义一个一个函数得到一个数字或字符串值的长度
function getLength(x: number | string) {
  // return x.length // error
  if (x.length) { // error
    return x.length
  } else {
    return x.toString().length
  }
}

# 类型断言

通过类型断言这种方式可以告诉编译器,“相信我,我知道自己在干什么”。 类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。 TypeScript 会假设你,程序员,已经进行了必须的检查。

类型断言有两种形式。 其一是 <> 语法,另一个为 as 语法

/* 
类型断言 (Type Assertion): 可以用来手动指定一个值的类型
语法:
    方式一: < 类型 > 值
    方式二:值 as 类型  tsx 中只能用这种方式
*/
/* 需求:定义一个函数得到一个字符串或者数值数据的长度 */
function getLength(x: number | string) {
  if ((<string>x).length) {
    return (x as string).length
  } else {
    return x.toString().length
  }
}
console.log(getLength('abcd'), getLength(1234))