一、认识TypeScript
1. JS 痛点
- ES5 以及之前的使用的 var 关键字关于作用域的问题
- 最初 JS 设计的数组类型并不是连续的内存空间
- 至今 JS 也没有加入类型检测机制
二、TypeScript 运行环境
1. TypeScript 的编译环境
- TypeScript 最终会被编译成 JavaScript 来运行,需要搭建对应的环境
- 在电脑上安装 TypeScript,这样可以通过 TypeScript 的 Compiler 将其编译成 JavaScript
graph TD
编写TypeScript代码main.ts --> 编译后的JavaScript代码main.js --> 浏览器
- 全局安装
- 安装命令
- npm install typescript -g
- 查看版本
- tsc --version
- 安装命令
三、TypeScript 变量声明
1. 变量的声明
- TypeScript 中定义变量需要指定标识符的类型
- 完整的声明格式如下:
- 声明了类型后TypeScript就会进行类型检测,声明的类型可以称之为类型注解(Type Annotation)
- var/let/const 标识符:数据类型 = 赋值;
- 给已声明的类型变量赋值其它类型值,会报错
- string是小写的,和String有区别
- string是TypeScript中定义的字符串类型,String是ECMAScript中定义的一个类
2. 变量的类型推断(推断)
- 在开发中,有时候为了方便起见,并不会声明每一个变量时都写上对应的数据类型,更希望通过TypeScript本身的特性帮助我们推断出对应的变量类型
- 在一个变量第一次赋值时,会根据后面的赋值内容的类型,来推断出变量的类型
四、JavaScript 数据类型
1. TypeScript 是 JavaScript 的一个超集
TypeScript >= ES6+ >= JavaScript
2. number类型
- 不区分整数类型(int)和浮点型(double),统一为number类型
- ES6新增了二进制和八进制的表示方法,TypeScript也是支持二进制、八进制、十六进制的表示
- 0b101:二进制
- 0o555:八进制
- 0xf23:十六进制
3. boolean类型
4. Array类型
- 数组类型的定义有两种方式
- string[]:
- Array<string>:泛型写法
5. Symbol类型
- 在 ES5中,不可以在对象中添加相同的属性名称的
- 也可以通过symbol来定义相同的名称,因为Symbol函数返回的是不同的值
- const s1: symbol = Symbol('title')
- const s2: symbol = Symbol('title')
- const person = { [s1]: '校长', [s2]: '老师' }
6. null和undefined类型
- 在 JavaScript 中, undefined 和 null 是两个基本数据类型
- 在 TypeScript 中,他们各自的类型也是 undefined 和 null,意味着既是实际值,也是自己的类型
- let u: undefined = undefined
7. 函数的参数类型
- 函数是 JavaScript 非常重要的组成部分,TypeScript 允许我们指定函数的参数和返回值的类型
- 参数的类型注解
- 声明函数时,可以在每个参数后添加类型注解,以声明函数接受的参数类型
8. 函数的返回值类型、
- 也可以添加返回值的类型注解,出现自函数列表的后面
- 和变量的类型注解一样,通常不需要返回类型注解,因为 TypeScript 会根据 return 返回值推断函数的返回类型
- 某些三方库为了方便理解,会明确指定返回类型;写不写全凭个人喜好
function sum(num1: number, num2: number): number {
return num1 + num2
}
9. 匿名函数的参数
- 匿名函数与函数声明会有一些不同
- 每当一个函数出现在 TypeScript 可以确定该函数会被如何调用的地方时,该函数的参数会自动指定类型
- 并没有指定 foreach item的类型,但是 item 推导出了类型
- 因为 TypeScript 会根据 foreach 函数的类型以及数组的类型推断出 item 的类型
- 该过程称为 上下文类型(contextual typing),因为函数执行的上下文可以帮助确定参数和返回值的类型
10. 对象类型
- 限定一个函数接受的参数是一个对象,如何限定?
- 使用对象类型
function a(point: {x: number, y: number}){
console.log(point.x)
console.log(point.y)
}
a({x: 10, y: 30})
- 使用一个对象来作为类型
- 在对象可以添加属性,并且告知TypeScript该属性需要什么类型
- 属性之间可以使用 , 或 ; 来分割,最后一个分隔符可选
- 每个属性的类型部分也是可选的,如果不指定,那么就是any类型
11. 可选类型
- 对象类型也可以指定哪些属性是可选的,可以在属性的后面添加一个 ?:
function a(point: {x: number, y: number, z?:number}){
console.log(point.x)
console.log(point.y)
console.log(point.z)
}
a({x: 10, y: 30})
a({x: 10, y: 30, z: 20})
五、TypeScript 数据类型
1. any 类型
- 在某些情况下,无法确定一个变量的类型,并且可能也会发生一些变化,此时可用any类型(类似Dart语言中的dynamic类型)
- any类型有点像一种讨巧的TypeScript手段
- 可以对any类型的变量进行任何操作,包括获取不存在的属性、方法
- 给一个any类型的变量赋值任何值,如数字、字符串的值
- 如果对于某些情况的处理过于繁琐不希望添加规定的类型注解,或者引入一些第三方库时,缺失了类型注解,此时可以使用any
2. unknown类型
- unknown 是 TypeScript 中比较特殊的一中类型,用于描述类型不确定的变量
- 和 any 类型有点类似,但是 unknown 类型的值上做任何事情都是不合法的
- 可以通过缩小类型或类型推断来处理 unknown 类型的数据
3. void 类型
- void通常用来指定一个函数是没有返回值的,那么它的返回值就是 void 类型
- 没写函数的任何返回值类型,默认返回值的类型就是 void,也可以显示指定void
- 注意事项
- 可以将 undefined 赋值给 void 类型,也就是函数可以返回 undefined
- 当基于上下文的类型推导(Contextual Typing)推导出函数返回类型为 void 时,并不会强制函数一定不能返回内容
- 如 foreach 遍历数组等
4. never 类型
- never 表示永远不会发生值的类型,如一个函数
- 如果一个函数中是一个死循环或者抛出一个异常,那么这个函数会返回东西么?
- 不会。那么写 void 类型或者其他类型作为返回值类型都不合适,此时可以用 never 类型
5. tuple 类型
- tuple 是元组类型
const info = [string, number, number] = ['m', 17, 180]
- tuple 和数组有什么区别呢?
- 数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中的。
- 可以放对象或元组中
- 元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型
- tuple 的应用场景
- 通常用作(函数)返回值,使用时非常方便