欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

程序员文章站 2022-06-24 19:44:17
...

前提需要有js的基础

TypeScript

产生背景

TypeScript 起源于使用JavaScript开发的大型项目 。由于JavaScript语言本身的局限性,难以胜任和维护大型项目开发。因此微软开发了TypeScript ,使得其能够胜任开发大型项目。

什么是TypeScript?

  • 以JavaScript为基础构建的语言
  • 一个JavaScript的超集
  • 可以在任何支持JavaScript的平台中执行
  • TypeScript扩展了JavaScript并添加了类型
  • TS不能被JS解析器直接执行 TS—编译—>JS

TypeScript增加了什么

  • 类型:抽象、枚举等
  • 支持ES的新特性
  • 添加ES不具备的新特性
  • 丰富的配置选项:比如TS可以被配置为编译成任何版本的JS
  • 强大的开发工具

TypeScript开发环境搭建

  1. 下载Node.js

  2. 安装node.js

  3. 使用npm全局安装typescript

    • 进入命令行

    • 输入:npm i -g typescript

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

  • 查看是否安装成功

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

  1. 创建一个ts文件

    (持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

  2. 使用tsc对ts文件进行编译

    (持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

  3. 自动生成JS文件

    (持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

基本类型

  • 类型声明

    • 如果类型声明和赋值分开

      let/const/var 变量名 : 类型

      (持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

    • 如果声明和赋值一起写,会自动进行类型检测

    (持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

  • 类型

    类型 例子 描述
    number 1,-33,20 任意数字
    string ‘hello’, “hello” 任意字符串
    boolean true,false 布尔值true或false
    字面量 其本身 限制变量的值就是该字面量的值
    any * 任意类型
    unknown * 类型安全的any
    void 空值(undefined) 没有值(或undefined)
    nerver 没有值 不能是任何值
    object {name: ‘abc’} 任意的JS对象
    array [1,12,3] 任意JS数组
    tuple [4,5] 元组,TS新增类型,固定长度数组
    enum enum{A,B} 枚举,TS中新增类型
    • 字面量

      let a: 10;
      a = 10;
      
      let b: "male" | "female"; // 赋值为"male" |或"female"
      b = "male";
      b = "female";
      b = "hello" // 报错 ERROR!
      
    • any

      表示是任意类型,一个变量设置类型为any后相当于对该变量关闭了TS的类型检测

      let a = any;  // 显式声明any
      let a; //隐式声明any
      // 赋值
      a = 10; // 正常
      a = 'hello'; // 正常
      a = true;  // 正常
      
    • unknown

      类型安全的any,不能直接给其他类型的变量

      let e: unknown;
      e = 10;
      e = 'hello';
      e = true;
      

      看似和any一样,其实不然。

      any举例:

      let s:string;
      let d;  // any
      s = d; // 不报错
      

      unknown举例:

      let e: unknown;
      let s: string;
      s = e; // 报错
      
      // 如果非要赋值
      // if语句
      if(typeof e === 'string') {
        s = e;
      }
      // 类型断言,告诉编译器e是字符串
      s = e as string;
      // 另外一种写法
      s = <string>e;
      
    • void

      主要作为返回值,用来表示空,以函数为例,就表示没有返回值的函数。

      function fn(): void {
        // ...
      }
      
    • never

      表示永远不会返回结果

      function fn2(): never{
        // ...
      }
      // 有一些函数永远不会返回结果
      function showError(): never{
        throw new Error('报错了!');
      }
      
    • object

      object表示一个js对象

      // 一般不使用这种声明
      let a: object;
      a = {};
      a = function () {
      
      }
      // 一般使用下面的写法,要求格式和类型
      let b: {name: string};
      b = {name: '孙悟空'}
      // 在属性名后面加上? 表示属性是可选的
      let c: {name: string, age?: number};
      c = {name: '孙悟空'}; // 不报错
      
      // 但是不能把需要的所有属性都写一边,所以就用下面的语法
      // [propName: string]: any便是任意类型的属性
      let d: {name: string, [propName: string]: any};
      c = {name: '猪八戒', age: 1, gender: '男'};
      
      // 声明function结构的类型声明
      // (形参: 类型, 形参: 类型) => 返回值
      let e: (a: number, b: number) => number;
      d = function(n1: number, n2: number): number {
        return 10;
      }
      
    • array

      // 声明1:类型[]
      let arr1: string[];
      arr1 = ['a', 'b', 'c'];
      // 声明2:Array<类型>
      let arr2: Array<number>;
      arr2 = [1, 2, 3];
      
    • tuple

      元组,固定长度的数组

      // 简单的声明
      let arr3: [string, string];
      arr3 = ['a', 'b'];
      arr3 = ['a', 'b', 'c']; //报错
      
    • enum

      枚举,把所有可能的类型列出来

      enum Gender{
        Male = 0;
        Female = 1;
      }
      
      let i: {name: string, gender: Gender};
      i = {
        name: '孙悟空',
        gender: Gender.Male; // 0
      }
      
      console.log(i.gender === Gender.Male);
      
    • | 和 &

      let a: number | string
      let b: {name: string} & {age: number};
      b = {name: '孙悟空', age: 18};
      
    • 类型的别名

      // 引例:
      let k: 1 | 2 | 3 | 4;
      let l: 1 | 2 | 3 | 4;
      // 麻烦
      // 解决
      type myType =  1 | 2 | 3 | 4;
      let k: myType;
      let j: myType;
      

编译文件配置

我们写一行代码手动敲tsc命令编译一次是很耗时的,相当麻烦,也无法自动编译,而且无法编译所有的ts文件。

所以目录下增加tsconfig.json配置文件用来编译所有的ts文件。

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

这时就算没有写内容,打开这个目录,执行tsc,它会自动编译这个目录下所有的ts文件成js文件,下面介绍各配置项

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

tsconfig.json常用的各配置项

以下列出常用的tsconfig.json配置

{
  /*
  tsconfig.json ts编译器的配置文件
  */
  /*
  "include" 用来指定哪些ts文件需要被编译
  ->  路径: ** 表示任意目录  * 表示任意文件
  */
  "include": [
    "./src/**/*"
  ],
  /*
  "exclude" 用来指定哪些ts文件不希望被编译,比如node_module下的ts文件
  默认值: ["node_modules", "bower_components", "jspm_packages"]
  */
  "exclude": [
    "./src/abc/*"
  ],
  /*
  "extends" 定义被继承的配置文件
  下面会让此配置文件中自动包含config下base.json中的所有配置信息
  */
  "extends": "./config/base",
  /*
  "files" 指定被编译文件的列表,只有需要编译的文件少时才会用到
  列表中的文件都会被TS编译器所编译
  */
  "files": [
    "core.ts",
    "sys.ts"
  ],
  /*
  "compilerOptions" 编译选项时配置文件中非常重要也比较复杂的配置选型
  在compilerOptions中包含多个子选项,用来完成对编译的配置
  */
  "compilerOptions": {
    // target
    // 设置ts代码编译成JS的目标版本
    // 可选值:ES3(默认),ES5,ES6/ES2015,ES7/ES2016,ES2017,ES2018,ES2019,ES2020,ES2021
    "target": "ES2015",
    // lib
    // 指定代码运行时所包含的库(宿主环境) 一般情况下不改动
    // 可选值:ES5,ES6/ES2015,ES7/ES2016,ES2017,ES2018,ES2019,ES2020,ESNext,DOM...
    "lib": ["ES2015", "DOM"],
    // module
    // 设置编译后代码使用的模块化系统,指定模块化的规范
    // 可选值:CommonJS,AMD,UMD,ES2020.ESNext,None,System
    "module": "CommonJS",
    // outDir
    // 用来指定编译后js文件所在的目录
    "outDir": "./distJS",
    // outFile
    // 将代码合并为一个文件,全局作用域中的代码会合并
    // 如果要合并几个模块,要用AMD或者System
    "outFile": "./distJS/app.js",
    // allowJs
    // 是否对js文件进行搬移,默认是false
    "allowJs": false,
    // checkJs
    // 是否检查js代码是否符合语法规范,默认是false
    "checkJs": false,
    // strict 建议开启
    // 所有严格检查的开关 默认false
    "strict": false,
    // removeComments
    // 是否移除注释,默认false
    "removeComments": false,
    // noEmit 
    // 不生成编译后的js文件
    "noEmit": false,
    // noEmitOnError
    // 当有错误时,它不会生成编译后的js文件,默认false
    "noEmitOnError": true,
    // alwaysStrict
    // 用来设置编译后的文件是否使用严格模式,默认false
    "alwaysStrict": false,
    // noImplicitAny
    // 检查隐式any,true为不允许隐式any 默认false
    "noImplicitAny": true,
    // noImplicitThis
    // 检查隐式this,来源不明确的this 默认false
    "noImplicitThis": true,
    // strictNullChecks
    // 严格的检查空值null隐患 默认值false
    "strictNullChecks": false
  }
}

使用webpack打包ts代码

安装webpack

npm i -D webpack webpack-cli typescript ts-loader

配置webpack

只讲ts有关的,打包css,js图片等loader配置可以看我另外一个文章

webpack.config.js

// 引入一个包
const path = require('path');
// webpack中的所有配置信息都应该写在module.exports中
module.exports = {
  // 指定入口文件
  entry: "./src/index.ts",

  // 指定打包文件所在的目录
  output: {
    // 指定打包文件的目录
    path: path.resolve(__dirname,'dist'),
    // 打包后文件的名字
    filename: "bundle.js"
  },

  // 指定wegpack打包时要使用的模块
  module: {
    // 指定要加载的规则
    rules: [
      {
        // test指定的时规则生效的文件
        test: /\.ts$/,
        // 要使用的loader
        use: 'ts-loader',
        // 要排除的文件
        exclude: /node_modules/
      }
    ]
  }
}

配置ts编译规则

tsconfig.json

{
  "compilerOptions": {
    "module": "ES2015",
    "target": "ES2015",
    "strict": true
  }
}

增加package.json中script的命令

"build": "webpack"

这样最基本的配置已经完成了

试编译ts代码

编写index.ts

function sum(a: number, b: number): number{
  return a + b;
}

console.log(sum(1, 10));

npm run build

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

报的错是没指定环境是生产模式还是开发模式

想要解决这个错误就在webpack配置文件里增加mode配置,指定模式即可。

安装html-webpack-plugin

npm i -D html-webpack-plugin

让webpack自动生成html

配置插件

// 引入一个包
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

// webpack中的所有配置信息都应该写在module.exports中
module.exports = {
  // 指定入口文件
  entry: "./src/index.ts",

  // 指定打包文件所在的目录
  output: {
    //...
  },

  // 指定wegpack打包时要使用的模块
  module: {
    //...
  },
  "mode":"development",
  // 配置webpack插件
  plugins: [
    new HtmlWebpackPlugin(),
  ]
}

这样它会在build以后自动生成html并且自动引入ts编译后的js文件

安装webpack-dev-server

npm i -D webpack-dev-server

可以让我们的项目跟浏览器联系在一起,代码一修改后自动刷新,展现在浏览器中

安装完后增加script命令

"strat": "webpack serve --open chrome.exe"

安装 clean-webpack-plugin

npm i -D clean-webpack-plugin

可以在每次新编译后,将dist文件夹里面的文件清空,把新的文件加进去,让dist文件夹里面都是最新编译的文件。

配置webpack,告诉它引用的模块

因为如果你再创建一个ts,在index.ts中引入了新建的ts,webpack并不知道新建的ts可以作为模块引入,它会报错。

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

增加webpack配置

  // 用来设置引入模块
  resolve: {
    extensions: ['.js', '.ts']
  }

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

安装babel.js以提高兼容性

因为现在编译出来的js为ES6的语法,对于像IE的兼容性很不好,所以现在引入babel.js将我们的语法编译成像ES5提高兼容性。

安装

npm i -D @babel/core @babel/preset-env babel-loader core-js

preset-env 是babel预置不同的环境使得兼容不同的浏览器

core-js 模拟js运行环境,可以让老浏览器很好的运行js

配置webpack

// 引入一个包
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const { CleanPlugin } = require('webpack');

// webpack中的所有配置信息都应该写在module.exports中
module.exports = {
  // 指定入口文件
  entry: "./src/index.ts",

  // 指定打包文件所在的目录
  output: {
    // 指定打包文件的目录
    path: path.resolve(__dirname,'dist'),
    // 打包后文件的名字
    filename: "bundle.js"
  },

  // 指定wegpack打包时要使用的模块
  module: {
    // 指定要加载的规则
    rules: [
      {
        // test指定的时规则生效的文件
        test: /\.ts$/,
        // 要使用的loader
        use: [
          // 配置babel
          {
            // 指定加载器
            loader: "babel-loader",
            // 设置babel
            options: {
              // 设置预定义的环境
              presets: [
                [
                  // 指定环境的插件
                  "@babel/preset-env",
                  // 配置信息
                  {
                    targets: {
                      // 指定兼容浏览器的版本
                      "chrome": "58",
                      "ie": "11",
                    },
                    // 指定corejs的版本
                    "corejs":"3",
                    // 使用corejs的方式"usage表示按需加载
                    "useBuiltIns":"usage"
                  }
                ]
              ]
            }
          },
          'ts-loader'
        ],
        // 要排除的文件
        exclude: /node_modules/
      }
    ]
  },
  "mode":"development",
  // 配置webpack插件
  plugins: [
    new HtmlWebpackPlugin({
      //title:"这是一个自定义的title"
      template: "./src/index.html"
    }),
    new CleanPlugin()
  ],
  // 用来设置引入模块
  resolve: {
    extensions: ['.js', '.ts']
  }
}

index.ts:

const abc = {name:'abc', age: 12};
console.log(abc);

不使用babel进行编译,他编译后的变量声明是const

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

使用babel进行编译,编译后变成了var声明变量

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

像ie11没有Promise,如果我们使用了Promise,corejs会产生效果,使用自己实现的promise加在编译后的js中

index.ts

const abc = {name:'abc', age: 12};
console.log(abc);
console.log(Promise);

进行编译,corejs会加入很多自己实现的东西

(持续更新中)干货! 快速上手typescript的学习笔记 (对比JS特性,环境搭建,webpack配置,ts编译配置)

但是这样在ie中还是会出错,因为webpack使用了箭头函数,我们可以增加配置项让webpack不使用箭头函数

output:{
   // ...
   // 告诉webpack不使用箭头函数
   environment: {
     arrowFunction: false
   }
}

这样ie就不会报错了

面向对象

以下话摘抄与尚硅谷的****

面向对象是程序中一个非常重要的思想,它被很多同学理解成了一个比较难,比较深奥的问题,其实不然。面向对象很简单那,简而言之就是程序之中所有的操作都需要通过对象来完成。

  • 举例来说
    • 操作浏览器需要用到window对象
    • 操作网页要用到document对象
    • 操作控制台要用到console对象

一切操作都要通过对象,也就是所谓的面向对象,那么对象到底是什么呢?这就要先说到程序是社么,计算机程序的本质就是对现实事务的抽象,抽象的反义词是具体,比如:照片是一个具体的人的抽象,汽车模型是对具体汽车的抽象等等。程序也是对事务的抽象,在程序中我们可以表示一个人,一条狗,一把枪,一颗子弹等等所有的事物,一个事物到了程序中就变成了一个对象。

在程序中所有的对象都被分成了两个部分,数据和功能,以人为例,人的姓名、性别、年龄、身高等属于数据,人可以说话吃饭睡觉,这些属于人的功能,数据在对象中被称为属性,而功能就被称为方法,所以简而言之,在程序中一切皆是对象。