什么是TypeScript?

  • TypeScript是JavaScript的超集,Typing代表强类型语言,是在JS的基础上加了一层类型定义
  • TypeScript会做类型推演和类型匹配
  • TypeScript的类型检查,在编译阶段就能发现错误,极大地避免了低级错误,规范了我们的代码
  • TypeScript支持JavaScript最新特性(ES6/7) ```typescript var button = document.getElementById(“query”) var num1 = document.getElementById(“num1”) as HTMLInputElement; var num1 = document.getElementById(“num2”) as HTMLInputElement;

function add(num1: number, num2: number) { return num1 + num2; }

button.addEventListener(“click”, () => { console.log(add(+num1.value, +num2.value)); });

  1. <a name="Ei9C4"></a>
  2. ### TypeScript开发环境搭建
  3. [typescript官方文档](https://www.typescriptlang.org/docs/handbook/typescript-tooling-in-5-minutes.html)
  4. 1. 安装NodeJS
  5. 2. 全局安装typescript
  6. ```bash
  7. npm install -g typescript
  8. # 或者
  9. yarn global add typescript
  1. 安装VSCode,`ctrl+``调出终端
  2. 安装好后查看版本

    1. node -v
    2. tsc -v
  3. 编译ts文件, 生成js文件

    1. tsc main.ts
  4. 运行js文件

    1. node main.js

    JS的版本

    ES6 = ES2015
    ES2016=ES7
    ES2017=ES8

用npm管理项目

使用命令npm init初始化项目,会生成package.json文件
安装lite-server

  1. npm install --save-dev lite-server
  2. #或者
  3. yarn add --dev lite-server

在package.json的scripts中添加start命令

  1. "scripts": {
  2. "start": "lite-server",
  3. "test": "echo \"Error: no test specified\" && exit 1"
  4. },

新建index.html文件,在其中引入main.js文件
使用命令**npm start**启动项目

TypeScript

使用letconst声明变量,极力避免使用var

boolean/number/string

  1. let a = true // 自动推断类型
  2. let isTrue: boolean // 手动指定类型
  3. const total: number = 0;
  4. let firstName: string = `Alex`

数组Array和元组Tuple

  1. // 数组
  2. let list1:number[] = [1,2,3,4]
  3. let list2:Array<number> = [1,2,3,4]
  4. let list3 = [1,2,3,4]
  5. let list4: any[] = [1, 'hello', true]
  6. // 元组
  7. let person1: [number, string] = [1, "alex"]
  8. person1.push("xxx") // bug
  • 元组是固定长度(2位),固定类型的特殊数组,是TypeScript新增的,JS没有,在声明时必须指定类型
  • Typescript中的元组还不完善,使用push可以突破元组的限制,无限添加元素

    联合(Union)与字面量(Literal)

    1. type A = string | number | boolean
    2. type B = 1 | 'hello' | true

    枚举类型(Enum)

    ```typescript enum Color { red, green, blue, }

console.log(Color.green) // 输出为1, 索引从0开始

enum Color2 { red = ‘red’, green = ‘green’, blue = 1, }

console.log(Color2.green) // 输出为green

Object.values(Color2) // 获取值

  1. <a name="qE5AF"></a>
  2. ### Any 与 unknown
  3. any是任意类型,只有运行时才能发现错误,any适合偷懒的时候使用<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1753813/1633316601810-c3b0fc99-619a-4b59-a409-dcdf20a9949c.png#clientId=uefcf0fa0-15c0-4&from=paste&height=99&id=uf2d83ee4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=126&originWidth=452&originalType=binary&ratio=1&size=8427&status=done&style=none&taskId=uab8366f3-3278-4a87-abae-0e6f6c5b9c7&width=355)<br />unknown保证了类型安全,必须做类型判断才能使用<br />![image.png](https://cdn.nlark.com/yuque/0/2021/png/1753813/1633316695319-927774b2-1a8b-438e-b365-71b74b536946.png#clientId=uefcf0fa0-15c0-4&from=paste&height=156&id=u19f92629&margin=%5Bobject%20Object%5D&name=image.png&originHeight=225&originWidth=511&originalType=binary&ratio=1&size=15826&status=done&style=none&taskId=ua761a432-8e01-4cb0-a45e-af65e0bf8f1&width=354.5)
  4. <a name="VJHlZ"></a>
  5. ### void, undefined, never
  6. void指返回值本身不存在
  7. ```typescript
  8. function printResult(): void {
  9. console.log("lalala")
  10. }

undefined指返回值存在,但未初始化

  1. function printResult(): undefined {
  2. console.log("lalala")
  3. return
  4. }

never指函数未执行完成:抛出异常或死循环了

  1. function printResult(): never {
  2. throw 'error'
  3. console.log('lalala')
  4. }

类型适配(类型断言) type assertion

  1. let msg:any = 'abc'
  2. // 2种方式使用类型适配
  3. let b = (<string>msg).endsWith('c')
  4. let c = (msg as string).endsWith('c')

使用类型断言必须清除地知道变量的类型,否则容易引发严重的错误

函数

可选参数或者默认值都要放在参数末尾

  1. const fn = (a: string, b: number = 1, c?:string) => {
  2. console.log(a, b, c)
  3. }

class

  1. interface IPoint {
  2. x: number
  3. y: number
  4. drawPoint: () => void
  5. getDistance: (p: IPoint) => number
  6. }
  7. class Point implements IPoint {
  8. x: number
  9. y: number
  10. constructor(x: number, y: number) {
  11. this.x = x
  12. this.y = y
  13. }
  14. drawPoint() {
  15. console.log('x: ', this.x, 'y: ', this.y)
  16. }
  17. getDistance(p: IPoint) {
  18. return Math.pow(p.x - this.x, 2) + Math.pow(p.y - this.y, 2)
  19. }
  20. }
  21. const aPoint = new Point(1, 2)
  22. const bPoint = new Point(3, 4)
  23. aPoint.drawPoint()
  24. console.log(aPoint.getDistance(bPoint))

访问修饰符 Access Modifier

默认是public, 不需要特别指明
如果在constructor的参数中使用访问修饰符,则不需要再额外声明和赋值

  1. class Point implements IPoint {
  2. // x: number
  3. // y: number
  4. constructor(public x: number, public y: number) {
  5. // this.x = x
  6. // this.y = y
  7. }
  8. // ...
  9. }

private禁止从外部访问, 私有变量一般前面加下划线
protected禁止从外部访问,但允许子类访问,
interface中都只能是public的
访问私有变量使用getter和setter

  1. class Point implements IPoint {
  2. // x: number
  3. // y: number
  4. constructor(private _x: number, private _y: number) {
  5. // this.x = x
  6. // this.y = y
  7. }
  8. drawPoint() {
  9. console.log('x: ', this._x, 'y: ', this._y)
  10. }
  11. getDistance(p: IPoint) {
  12. return Math.pow(p.x - this._x, 2) + Math.pow(p.y - this._y, 2)
  13. }
  14. set x(value: number) {
  15. if(value < 0)
  16. throw new Error('x必须大于0')
  17. this._x = value
  18. }
  19. get x() {
  20. return this._x
  21. }
  22. set y(value: number) {
  23. if(value < 0)
  24. throw new Error('y必须大于0')
  25. this._y = value
  26. }
  27. get y() {
  28. return this._y
  29. }
  30. }

编译时报错
image.png
在命令中指定target

  1. tsc -t es5 main.ts

泛型

泛型,允许我们在定义的时候不具体指定类型,而是泛泛地说一种类型,并在函数调用的时候再指定具体的参数类型。
image.png
上面代码的意思是对 T 进行处理,是返回一个 T 的子集
TypeScript 2小时速学 - 图3
TypeScript 2小时速学 - 图4
简单来说,将类型看成值,然后对类型进行编程,这就是泛型的基本思想。泛型类似我们平时使用的函数,只不过其是作用在类型上,思想上和我们平时使用的函数并没有什么太多不同,泛型产生的具体类型也支持类型的操作。

  1. function id<T, U>(arg1: T, arg2: U): T {
  2. return arg1;
  3. }

参考文章