前言
从弱类型到强类型,开发更加严谨,是前端发展的必然趋势。TypeScript 作为 JS 的超集,自然也推动着前端开发人员去学习 TS,特别是 Vue 3 出现之后且大部分第三方库都有 TS 编译文件之后。TS 的掌握就渐渐变成一项基础技能。
开始 TypeScript
学习准备
开始 TypeScript(以下简称 TS)正式学习之前,推荐做好以下准备:
- Node 版本 > 8.0
- IDE(推荐 VS Code,TS 是微软推出的,VS Code 也是微软推出,且轻量。对 TS 代码更友好)
初识 TypeScript
打开 TypeScript 官网可以看到官方对 TS 的定义是这样的
JavaScript and More
A Result You Can Trust
Gradual Adoption
这三个点就很好地诠释了 TypeScript 的特性。在此之前,先来简单体验下 TypeScript 给我们的编程带来的改变。
这是一个 .js 文件代码:
let a = 123
a = '123'
这是 .ts 文件代码:
let b = 123
b = '123'
当我们在 TS 文件中试图重新给 b 赋值的时候,发生了错误,鼠标移动到标红处,系统提示:
Type ·"123"' is not assignable to type 'number'
原因是什么呢?
答案很简单,在 TS 中所有变量都是静态类型,let b = 123
其实就是 'let b:number = 123'
。b 只能是 number 类型的值,不能赋值给其他类型。
TypeScript 的优势
- TS 静态类型,可以让我们在开发过程中发现问题
- 更友好的编辑器自动提示
- 代码语义清晰易懂,协作更方便
配上代码来好好感受下这三个优势带给我们的编程体验有多直观,建议边在编辑器上敲代码。
先上最熟悉的 JS:
function add(data) {
return data.x + data.y
}
add() //当直接这样写,在运行的时候才会有错误告知
add({x:2,y:3})
再上一段 TS 代码(如果对语法有疑问可以先不纠结,后续会有讲解,此处可以先带着疑问)
interface Point { x: number, y: number }
function tsAdd(data: Point): number {
return data.x + data.y
}
tsAdd() //直接这样写,编辑器有错误提示
tsAdd({ x: 1,y: 123})
当我们在 TS 中调用 data 变量中的属性的时候,编辑器会有想 x、y 属性提示,并且我们直接看函数外部,不用深入,就能知道 data 的属性值。这就是 TS 带给我们相比于 JS 的便捷和高效。
TypeScript 环境搭建
搭建 TypeScript 环境,可以直接在终端执行命令:
npm install -g typescript
然后我们就可以直接 cd 到 ts 文件夹下在终端运行:
tsc demo.ts
tsc 简而言之就是 typescript complaire,对 demo.ts 进行编译,然后我们就可以看到该目录下多了一个同名的 JS 文件,可以直接用 Node 进行编译。
到这里我们就可以运行 TS 文件了,但是这只是一个文件,而且还要先手动编异成 TS 在手动运行 Node,有没有一步到位的命令呢?当然有,终端安装 ts-node:
npm install -g ts-node
这样我们可以直接运行:
ts-node demo.ts
来运行 TS 文件,如果要初始化 ts 文件夹,进行 TS 相关配置,可以运行:
tsc --init
关于相关配置,这里我们先简单提下,后面将会分析常用配置,可以先自行打开 tsconfig.json 文件,简单看下其中的配置,然后带着疑问继续往下看。
再理解下 TypeScript 中的 Type
正式介绍 TS 的语法之前,还需要再把开篇提到的静态类型再来说清楚一些。
const a: number = 123
之前说过,代码的意思是 a 是一个 number 类型的常量,且类型不能被改变。这里我要说的深层意思是,a 具有 number 的属性和方法,当我们在编辑器调用 a 的属性和方法的时候,编辑器会给我们 number 的属性和方法供我们选择。
TS 不仅允许我们给变量定义基础类型,还可以定义自定义类型:
interface Point {
x: number
y: number
}
const a: Point = {
x: 2,
y: 3
}
把 a 定义为 Point 类型,a 就拥有了 Point 的属性和方法。而我们把 a 定义为 Point 类型之后,a 必须 Point 上 的 x 和 y 属性。这样我们就把 Type 理解的差不多了。
TypeScript 的类型分类
类比于 JavaScript 的类型,TypeScript 也分为基础类型和引用类型。
原始类型
原始类型分为 boolean、number、string、void、undefined、null、symbol、bigint、any、never。
JS 中也有的这里就不多解释,主要说下之前没有见过的几种类型,但是需要注意一下的是我们在声明 TS 变量类型的时候都是小写,不能写成大写,大写是表示的构造函数。
void 表示没用任何类型,通常我们会将其赋值给一个没有返回值的函数:
function voidDemo(): void {
console.log('hello world')
}
bigint 可以用来操作和存储大整数,即使这数已经超出了 JavaScript 构造函数 Number 能够表示的安全整数范围,实际场景中使用较少,有兴趣的同学可以自行研究下。
any 指的是任意类型,在实际开发中应该尽量不要将对象定义为 any 类型:
let a: any = 4
a = '4'
never 表示永不存在的值的类型,最常见的就是函数中不会执行到底的情况:
function error(message: string): never {
throw new Error(message)
console.log('永不执行')
}
function errorEmitter(): never {
while(true){}
}
引用类型
对象类型:赋值时,内必须有定义的对象属性和方法。
const person: {
name: string
age: number
} = {
name: 'aaa'
age: 18
}
数组类型:数组中每一项都是定义的类型。
const numbers: number[] = [1, 2, 3]
类类型:可以先不关注写法,后面还会详细讲解。
class Peron {}
const person: Person = new Person()
类型的介绍差不多就这么些知识点,先在脑海里有个印象,不懂的地方可以继续带着疑问往下看。
TypeScript 类型注解和推断
之前已经讲过 TypeScript 的类型和它的类型种类,这一小节还是想继续把有关类型的知识讲全,那么就是类型注解和类型推断。
类型注解
let a: number
a = 123
上面代码中这种写法就是类型注解,通过显式声明,来告诉 TS 变量的类型:
let b = 123
这里我们并没有显式声明 b 的类型,但是我们在编辑器中把光标放在 b 上,编辑器会告诉我们它的类型。这就是类型推断。