1、TypeScript是什麼

  • 以JavaScript為基礎構建的語言,一個JavaScript的超集
  • 對JS進行了拓展,向JS中引入型別的概念,並且添加了許多新的特性
  • 支援在任何支援JavaScript的平臺中執行
  • TS的最終目的是為了專案易維護,易書寫

2、TypeScript增加了什麼

  • 增加了型別,增加支援ES的新特性,增加ES不具備的新特性
  • 增加豐富的配置選項,相較於JS而言,TS擁有了靜態型別,更加嚴格的語法,更強大的功能,TS可以在程式碼執行前就完成程式碼的檢查,減小了執行時異常的機率
  • 相同的功能用TS的程式碼量遠大於JS實現,但由於TS的程式碼結構更加清晰,變數型別更加明確,在後期程式碼的維護中TS遠遠勝於JS

3、TypeScript環境的搭建

1、下載node.js

2、安裝node.js

3、使用npm全域性安裝typescript

  • 進入命令列
  • 輸入 npm install -g typescript

4、建立一個TS檔案

5、使用tsc對檔案進行編譯

  • 在檔案所在目錄開啟終端
  • 輸入 tsc xxx.ts

6、如果編輯器不能tsc編輯是沒有cmd的許可權,給命令列工具管理員許可權就可解決問題 附連結

4、TypeScript的基本型別

  • 型別宣告

型別宣告是TS非常重要的一個特點,通過型別宣告可以指定TS中變數、形參、實參的型別,指定型別後,當為變數賦值時,TS編譯器會自動檢查值是否符合型別宣告,符合就賦值否則就報錯。總結:型別宣告給變數設定了型別,是的變數只能儲存某種型別的值

let 變數:型別
let 變數:型別 = 值
function fn(形參:型別,形參:型別):型別{}//外面的型別限制了fn的返回值的型別 // never 表示永遠不會返回結果
function fnx(): never{
throw new Error('報錯了!');
}
  • 自動型別判斷

    • TS擁有自動的型別判斷機制
    • 當對變數的宣告和賦值是同時進行的
    • 所以如果你的變數的宣告和賦值是同時進行的,可以省略型別宣告
  • 型別

    型別 例子 描述
    number 1,33,2.5 任意數字
    string 'hi',"hi",hi 任意字串
    boolean true、false 布林值true或false
    字面量 其本身 限制變數的值就是該字面量的值
    any * 任意型別
    unknown * 型別安全的any
    void 空值(undefined) 沒有值(或undefined)
    never 沒有值 不能是任何值
    object {name:'肉絲'} 任意的JS物件
    array [1,2,3] 任意JS陣列
    tuple [4,5] 元素,TS新增型別,固定長度陣列
    enum enum{A,B} 列舉,TS中新增型別
  • number

    • let decimal:number = 6 //十進位制
      let hex:number = 0xf00d //十六進位制
      let binary:number = 0b1010 //二進位制
      let octal:number = 0o744 //八進位制
      let big:bigint = 100n // 大位元組
  • boolean

    • let isDone:boolean = false
  • string

    • let color:string = 'blue'
      color = 'red' let fullNmae:string = `Bob Bobbington`
      let age:number = 37
      let sentence:string = `Hello , my name is ${fullname}` I'll be ${age + 1} years old next month
  • 字面量

    • 也可以使用字面量去指定變數的型別,通過字面量可以確定變數的取值範圍

    • let color:'red' | 'blue' | 'black'
      let num:1 | 2 | 3 | 4 | 5 ;
  • any

    • let d:any = 4
      d = 'hello'
      d = true
      // 存在的問題是變數d可以賦值給其他變數
  • unknown

    • let unusable:unknown = undefined
  • never

    • function error(message:string):never {
      throw new Error(message)
      }
  • object (沒啥用)

    • let obj:object = {}
  • tuple

    • 元組,規定了元素的型別順序必須完全對照的

    • let x: [string,number]
      x = ["hello",10]
    • 元組型別允許在元素型別字尾一個 ? 來說明元素是可選的:

      • const list :[number,string?,boolean?]
        list = [1,'calm',true]
        list = [10,'calm']
        list = [10]
    • 元組型別的Rest使用

  • array

    • let list : number[] = [1,2,3]
      let list : Array<number> = [1,2,3]
  • 型別斷言

    • 有些情況下,變數的型別對於我們來說是很明確,但是TS編譯器卻並不清除,此時可以通過型別斷言來告訴編譯器變數的型別,斷言的兩種形式

      • 第一種

        • let someValue : unknown = "this is a string"
          let strLength : number = (someValue as string).length
      • 第二種

        • let someValue : unknown = "this is a string"
          let strLength : number = (<string>someValue).length

5、TypeScrip編譯選項

  • 自動編譯檔案

    • 編譯檔案時,使用-w命令後,TS編譯器會自動監視檔案的變化,並在檔案發生變化時對檔案進行重新編譯

      tsc example.ts -w
  • 自動編譯整個專案

    • 如果直接使用tsc指令,則可以自動將當前專案下的所有的檔案編譯為js檔案,但是直接使用tsc命令的前提是要現在專案根目錄下建立一個ts配置檔案 tsconfig.json

    • TSCONFIG.JSON是一個JSON檔案,新增配置檔案後,只需tsc命令即可完成對整個專案的編譯

    • 配置選項

      • include

        • 定義希望被編譯檔案的所在的目錄

        • 預設值:["**/*"]

        • 示例

          • "include":["src/**/*","test/**/*"]
          • 上述示例中,所有src目錄和tests目錄下的檔案都會被編譯

  • exclude

    • 定義需要排除在外的目錄

    • 預設值:["node_modules", "bower_components", "jspm_packages"]

    • 示例:

      • "exclude": ["./src/hello/**/*"]
      • 上述示例中,src下hello目錄下的檔案都不會被編譯

  • extends

    • 定義被繼承的配置檔案

    • 示例:

      • "extends": "./configs/base"
      • 上述示例中,當前配置檔案中會自動包含config目錄下base.json中的所有配置資訊

  • files

    • 指定被編譯檔案的列表,只有需要編譯的檔案少時才會用到

    • 示例:

      • "files": [
        "core.ts",
        "sys.ts",
        "types.ts",
        "scanner.ts",
        "parser.ts",
        "utilities.ts",
        "binder.ts",
        "checker.ts",
        "tsc.ts"
        ]
      • 列表中的檔案都會被TS編譯器所編譯

    • compilerOptions

      • 編譯選項是配置檔案中非常重要也比較複雜的配置選項

      • 在compilerOptions中包含多個子選項,用來完成對編譯的配置

        • 專案選項

          • target

            • 設定ts程式碼編譯的目標版本

            • 可選值:

              • ES3(預設)、ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext
            • 示例:

              • "compilerOptions": {
                "target": "ES6"
                }
              • 如上設定,我們所編寫的ts程式碼將會被編譯為ES6版本的js程式碼

          • lib

            • 指定程式碼執行時所包含的庫(宿主環境)

            • 可選值:

              • ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext、DOM、WebWorker、ScriptHost ......
            • 示例:

              • "compilerOptions": {
                "target": "ES6",
                "lib": ["ES6", "DOM"],
                "outDir": "dist",
                "outFile": "dist/aa.js"
                }
          • module

            • 設定編譯後代碼使用的模組化系統

            • 可選值:

              • CommonJS、UMD、AMD、System、ES2020、ESNext、None
            • 示例:

              • "compilerOptions": {
                "module": "CommonJS"
                }
          • outDir

            • 編譯後文件的所在目錄

            • 預設情況下,編譯後的js檔案會和ts檔案位於相同的目錄,設定outDir後可以改變編譯後文件的位置

            • 示例:

              • "compilerOptions": {
                "outDir": "dist"
                }
              • 設定後編譯後的js檔案將會生成到dist目錄

          • outFile

            • 將所有的檔案編譯為一個js檔案

            • 預設會將所有的編寫在全域性作用域中的程式碼合併為一個js檔案,如果module制定了None、System或AMD則會將模組一起合併到檔案之中

            • 示例:

              • "compilerOptions": {
                "outFile": "dist/app.js"
                }
          • rootDir

            • 指定程式碼的根目錄,預設情況下編譯後文件的目錄結構會以最長的公共目錄為根目錄,通過rootDir可以手動指定根目錄

            • 示例:

              • "compilerOptions": {
                "rootDir": "./src"
                }
          • allowJs

            • 是否對js檔案編譯
          • checkJs

            • 是否對js檔案進行檢查

            • 示例:

              • "compilerOptions": {
                "allowJs": true,
                "checkJs": true
                }
          • removeComments

            • 是否刪除註釋
            • 預設值:false
          • noEmit

            • 不對程式碼進行編譯
            • 預設值:false
          • sourceMap

            • 是否生成sourceMap
            • 預設值:false
        • 嚴格檢查

          • strict

            • 啟用所有的嚴格檢查,預設值為true,設定後相當於開啟了所有的嚴格檢查
          • alwaysStrict
            • 總是以嚴格模式對程式碼進行編譯
          • noImplicitAny
            • 禁止隱式的any型別
          • noImplicitThis
            • 禁止型別不明確的this
          • strictBindCallApply
            • 嚴格檢查bind、call和apply的引數列表
          • strictFunctionTypes
            • 嚴格檢查函式的型別
          • strictNullChecks
            • 嚴格的空值檢查
          • strictPropertyInitialization
            • 嚴格檢查屬性是否初始化
        • 額外檢查

          • noFallthroughCasesInSwitch

            • 檢查switch語句包含正確的break
          • noImplicitReturns
            • 檢查函式沒有隱式的返回值
          • noUnusedLocals
            • 檢查未使用的區域性變數
          • noUnusedParameters
            • 檢查未使用的引數
        • 高階

          • allowUnreachableCode

            • 檢查不可達程式碼
            • 可選值:
              • true,忽略不可達程式碼
              • false,不可達程式碼將引起錯誤
          • noEmitOnError
            • 有錯誤的情況下不進行編譯
            • 預設值:false

6、TypeScrip的打包

通常情況下,實際開發中我們都需要使用構建工具對待嗎進行打包,TS同樣也可以結合構建工具一起使用,下邊以webpack為例介紹一下如何結合構建共建工具使用TS

  • 步驟

    • 1.初始化專案

      • 進入專案目錄,執行命令 npm init -y
      • 主要作用:建立package.json
    • 2.下載構建工具

      • npm i -D webpack-cli webpack-dev-server typescript ts-loader clean-webpack-plugin
      • 共安裝七個包分別是
        • webpack :構建工具
        • webpack-cli :webpack的命令列工具
        • webpack-dev-server :webpakc的開發伺服器
        • typescript :ts的編譯器
        • ts-loader :ts載入器,在webpack中編譯ts檔案
        • html-webpack-pluigin :webpakc中html外掛,用來自動建立html檔案
        • clean-webpakc-plugin : webpack中的清除外掛,每次構建都會先清除目錄
    • 3.根目錄檔案下建立webpack的配置檔案webpack.config.js

      const path = require("path")
      const HtmlWebpackPlugin = require("html-webpack-plugin")
      const {cleanWbpackPlugin} = require("clean-webpack-plugin")
      module.exports = {
      optimization:{
      minimize: false // 關閉程式碼壓縮,可選
      }, entry: "./src/index.ts", devtool: "inline-source-map", devServer: {
      contentBase: './dist'
      }, output: {
      path: path.resolve(__dirname, "dist"),
      filename: "bundle.js",
      environment: {
      arrowFunction: false // 關閉webpack的箭頭函式,可選
      }
      }, resolve: {
      extensions: [".ts", ".js"]
      }, module: {
      rules: [
      {
      test: /\.ts$/,
      use: {
      loader: "ts-loader"
      },
      exclude: /node_modules/
      }
      ]
      }, plugins: [
      new CleanWebpackPlugin(),
      new HtmlWebpackPlugin({
      title:'TS測試'
      }),
      ] }
    • 4.根目錄下建立tsconfig.json,配置可以根據自己需要

      {
      "complierOptions":{
      "target":"ES2015",
      "module": "ES2015",
      "strict": true
      }
      }
    • 5.修改package.json新增如下配置

      {
      ...略...
      "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "build": "webpack",
      "start": "webpack serve --open chrome.exe"
      },
      ...略...
      }
    • 6.在src下建立ts檔案,並在命令列執行 npm run build程式碼進行編譯,或者執行 npm start 來啟動開發伺服器

配置後的完整webpack.config.js截圖

package.json的完整配置

7、TypeScrip的相容性

通過一系列的配置,TS和webpack已經打包在了一起,實際開發中除了webpack還需要結合babel來對程式碼進行轉換以使其可以相容更多的瀏覽器,在上述步驟的基礎上,在通過下步驟再講babel引入到專案中

1 . 安裝依賴包

  • npm i -D @babel/core @babel/preset-env babel-loader core-js
  • 共安裝了4個包,分別是:
    • @babel/core

      • babel的核心工具
    • @babel/preset-env
      • babel的預定義環境
    • @babel-loader
      • babel在webpack中的載入器
    • core-js
      • core-js用來使老版本的瀏覽器支援新版ES語法

2.修改webpack.config.js配置檔案

module: {
rules: [
{
test: /\.ts$/,
use: [
//ts結尾的檔案用兩個loader,分別對應兩個物件的配置
{
loader: "babel-loader",
options:{
presets: [
[
"@babel/preset-env",
{
"targets":{
"chrome": "58",
"ie": "10"
},
"corejs":"3",
"useBuiltIns": "usage"
}
]
]
}
},
{
loader: "ts-loader", }
],
exclude: /node_modules/
}
]
}

配置成功之後,使用TS編譯的檔案會被tsloader和babel處理,是的程式碼可以在大部分瀏覽器中直接使用,可以在配置選項的targets中指定要相容的瀏覽器版本,針對ie我們一般只相容到10