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
- 嚴格檢查屬性是否初始化
- strict
-
額外檢查
- noFallthroughCasesInSwitch
- 檢查switch語句包含正確的break
- noImplicitReturns
- 檢查函式沒有隱式的返回值
- noUnusedLocals
- 檢查未使用的區域性變數
- noUnusedParameters
- 檢查未使用的引數
- noFallthroughCasesInSwitch
-
高階
- allowUnreachableCode
- 檢查不可達程式碼
- 可選值:
- true,忽略不可達程式碼
- false,不可達程式碼將引起錯誤
- noEmitOnError
- 有錯誤的情況下不進行編譯
- 預設值:false
- allowUnreachableCode
-
-
-
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語法
- @babel/core
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