TypeScript的基本使用(1)
簡介
- js
- 優點:不容易報錯
- 缺點:
- ES6前使用面向物件比較麻煩(需要結合原型+建構函式);
- 沒有變數型別,會根據值來定義資料型別;js的變數是動態型別--可能會導致後面做運算時因為值發生改變,資料型別不匹配可能導致不會報錯,只有當程式執行到才會報錯。
- js定義函式時引數沒有型別的限制,我們可以在呼叫函式時傳任意資料型別,這樣就導致在執行某個語句後程序才出現報錯的情況
- ts
- 是微軟開發的,為了解決js所帶來的缺點,但不是為了替代js(因為js對於前端的影響非常大)
- 引入了資料型別,讓js從動態語言轉成靜態語言。即變數宣告時可以指定型別,型別一旦執行不能發生變化,否則會提示報錯(但還是可以編譯,後期我們可以通過webpack配置解決)。
- 目前情況下,ts檔案不能直接被JS解析器直接執行。即ts檔案不能在瀏覽器上直接執行
- ts可以通過配置讓js變得嚴謹或者鬆散
- ts中可以使用js中所有的語法
typescript編譯
預設情況下.ts
檔案是不能直接在瀏覽器使用的,需要通過node
中的typescript
進行編譯生成js。
步驟:
- 下載並安裝
Node.js
- 使用npm全域性安裝
typescript
npm i -g typescript
- 建立
hello.ts
檔案,並編寫程式碼
let a:string = "hello typescript"
- 使用
tsc
命令進行編譯
tsc hello.tsc
基本型別
型別有:number、string、boolean、字面量、any、unknown、void、never、object、array、tuple、enum
用法:
let a:number = 20
字面量
let n1:10
n1 = 10
# n1 = 20 報錯
unknown型別和any型別
- 可以將任意型別的值賦值給unknown型別或any型別的變數;
- 可以將any型別的變數賦值可以任意型別的變數;但是不能將unknown型別的變數賦值給任意型別(any型別除外)的變數
- 簡單理解為any會導致原本變數定義的資料型別不起作用了;或者理解為any權力最大,可以做任何的賦值操作。所以如果一個型別不確定時推薦使用unknown
let n1:unknown
let n2
n1 = 10
n1 = "hello"
n2 = 20
n2 = "ts"
let n3:string = "ok"
n3 = n2
# n3 = n1 這裡會報錯
型別斷言
有些情況下,變數的型別對於我們來說是很明確,但是TS編譯器卻並不清楚,此時,可以通過型別斷言來告訴編譯器變數的型別,一般用在變數設定為unknown
型別時
let n1:unknown
let s = "hello"
n1 = "ts"
# s = n1 報錯
# 方式1: 變數 as 型別
s = n1 as string;
# 方式2: <型別>變數
s = <string>n1
物件
let o :{name:string} = {name:'zs'}
# 下面會報錯
# let o: { name: string } = { name: 'zs', age: 20 }
# 屬性設定多個;propName是變數別名,可以隨意起
let o1:{name:string,[propName:string]:any} = {name:'ls',age:18}
函式
let sum: (n1: number, n2: number) => number
sum = function (n1, n2) {
return n1 + n2
}
陣列
let arr1: string[];
arr1 = ['i','love','ts']
let arr2: Array<number>;
arr2 = [10,20,30]
元組
固定長度的陣列
let t1: [string,number]
t1 = ['ok',200]
列舉
enum Gender{
Male,
Female
}
let o:{name:string,gender:Gender}
o = {name:'莉莉',gender:Gender.Female}
其他
或者
# n1的值可以是10或者string
let n1: 10 | string
n1 = 'hello'
n1 = 10
並且
let j: { name: string } & { age: number };
j = {name: '孫悟空', age: 18};
編譯選項
自動編譯單個檔案
使用 -w 指令後,TS編譯器會自動監視檔案的變化,並在檔案發生變化時對檔案進行重新編譯。【-w,表示watch】
tsc -w hello.ts
自動編譯整個資料夾
tsconfig.json是ts編譯器的配置檔案,ts編譯器可以根據它的資訊來對程式碼進行編譯
- 在專案根目錄下建立空的
tsconfig.json
檔案 - 然後執行
tsc -w
命令會實時監控當前目錄以及子目錄下的所有檔案的變化,對.ts
字尾的檔案進行自動編譯
編譯子選項
include
- 預設情況下當前目錄以及子目錄下的所有檔案都會進行編譯,如果要對某幾個目錄下的檔案進行編譯的話,則需要指定此選項。
- 預設值為:
["**/*"]
// 對src、test目錄下的所有檔案以及所有子檔案都進行編譯
"include": ["src/**/*","test/**/*"]
exclude
- 定義不需要進行編譯的目錄
"exclude":["node_modules"]
extends
- 定義多個配置檔案,當配置檔案需要按結構進行分離時可採取此方式
// 會自動包含config目錄下的basic.json檔案
"extends": "./config/basic"
files
- 指定被編譯的檔案列表
"files":["1.ts","2.ts","3.ts"]
compilerOptions
重點
- 此選項包含多個子選項,用來完成對編譯的配置
target
- 設定ts程式碼編譯的目標版本
- 可選值:ES3(預設)、ES5、ES6/ES2015、ES7/ES2016、ES2017、ES2018、ES2019、ES2020、ESNext
"compilerOptions":{
"target":"ES6"
}
outDir
- 預設情況下,編譯後的js檔案會和ts檔案位於相同的目錄,設定outDir後可以改變編譯後文件的位置
"compilerOptions": {
"outDir": "dist"
}
outFile
- 預設情況下一個ts檔案對應編譯成一個js檔案,如果需要打包成一個js檔案的話則可以設定此選項
"compilerOptions":{
"outFile":"dist/bundle.js"
}
allowJs
- 預設情況下不對js檔案進行編譯,如果需要進行編譯的話則可以設定此選項
"compilerOptions":{
"allowJs": true
}
removeComments
- 預設情況下會對註釋進行打包輸出,如果在打包檔案中不想輸出註釋內容則可以設定此選項
"compilerOptions":{
"removeComments": true
}
noEmit
- 預設情況下會對程式碼進行編譯,可以看到編譯生成的檔案,如果不想編譯生成檔案則可以設定此選項
"compilerOptions":{
"noEmit": true
}
module
- 指定要使用的模組化規範
- 可選值有:none, commonjs, amd, system, umd,es6, es2015, es2020, esnext
noEmitOnError
- 預設情況下語法錯誤也能進行編譯,如果錯誤不想編譯則可以設定此選項
"compilerOptions":{
"noEmitOnError": true,
}
strict
- 開啟嚴格模式,開發中會開啟,讓程式更嚴謹
"compilerOptions":{
"strict": true,
}
設定了嚴格模式後,會對程式碼進行空值的判斷。如果存在空值的可能則需進行下面的處理
let btn = document.querySelector("btn")
// 如果btn為空則不進行事件函式的處理
btn?.onclick=function(){
alert('test')
}
Webpack使用TS[待驗證]
- 通常情況下,實際開發中我們都需要使用構建工具對程式碼進行打包,TS也可以結合構建工具一起使用。
- 簡單來說,使用webpack對ts進行編譯生成js。
使用步驟如下:
- 使用
npm ini -y
初始化專案 - 安裝開發時依賴
npm install -D webpack webpack-cli typescript ts-loader
- 根目錄下建立
webpack.config.js
檔案
const path = require('path')
module.exports = {
entry: './src/index.ts',
output: {
path: path.resolve(__dirname,'dist'),
filename: 'bundle.js'
},
module:{
rules:[
{
test:/\.ts$/,
use:'ts-loader',
exclude: /node-modules/
}
]
},
/*
預設情況下,xx.ts不能直接使用"import"和"export"的方式 載入或者匯出
解決ts檔案可以使用"import"或"export"方式載入或匯出
*/
resolve:{
extensions: [".ts",".js"]
}
}
- 建立
tsconfig.json
配置檔案,指定ts編譯時的規則
{
"compilerOptions": {
"module": "ES2015",
"target": "ES2015",
"strict": true
}
}
package.json
中的script
屬性配置打包命令
{
"script":{
"build": "webpack"
}
}
- 執行打包命令
npm run build
注意
- 在使用import匯入檔案時不能新增檔名字尾否則會報錯。比如: import {n1} from './a'
babel[待驗證]
-
JS中有不同的版本,比如:ES5,ES6,ES2020...等等。當我們採用新版本的JS去寫程式碼時,低版本的瀏覽器無法識別,所以需要有一種可以將新語法的轉換成舊版的,這樣才能讓低版本的瀏覽器去識別。
-
其中
tsconfig.json
的compilerOptions
屬性有target
選項,我們可以指定編譯成js的版本,它只能做JS中簡單的語法轉換,但對於新增的技術它是不支援的(比如:ES6的Promise),這個時候就需要使用到babel
,可以相容更多的瀏覽器。 -
babel的作用
- 把新語法轉換成舊語法
- 把新的類、物件轉換成低版本瀏覽器支援的類。
- 為了讓程式碼有更好的相容性,可以在不同的瀏覽器中使用,使用babel來幫助我們解決相容性的問題
步驟:
- 安裝開發時依賴
cnpm i -D @babel/core @babel/preset-env babel-loader core-js
- @babel/core --核心庫
- @babel/preset-env ---預設環境。我們需要相容不同的瀏覽器環境,這個模組裡面定義好了轉換的程式碼
- babel-loader的作用是將 babel和webpack結合的一款工具
- core-js的作用是模擬js的執行環境,讓老版本的瀏覽器可以使用到新標準的技術。裡面裝有所有相容新功能的程式碼,在開發中我們經常是按需載入
- webpack.config.js配置
module:{
rules:[
{
test:/\.ts$/,
use:[
//多個loader進行處理,則use使用陣列的形式
// 多個loader的執行順序是從後往前。
// ts-loader的作用是將ts轉換為js;babel-loader的作用是將js轉換為低版本瀏覽器可識別的js程式碼
// 如果loader需要詳細的配置,則將字串形式轉換為物件的形式
{
loader:"babel-loader",
options:{
// 設定預定義的環境【也就是假設你的程式碼是要在哪些環境下執行】
presets:[
[
"@babel/preset-env",
{
//指定瀏覽器的版本
targets:{
// 相容chrome的58版本
"chrome":"58",
"IE":"11" //也就是說相容所有低版本的瀏覽器
},
//指定corejs的版本 【和當前安裝的版本一致即可】
"corejs": "3",
// 使用corejs的方式
"useBuiltIns": "usage" //按需載入
}
]
]
}
},
"ts-loader"
]
}
]
}
-
使用上述配置和不使用上述配置,然後設定
tsconfig.json
中的compilerOptions
屬性的target
屬性配置為ES2015
(這個就是ES6版本),測試ts檔案中使用const
定義變數的形式 是否在打包後的js檔案中轉換。-
不使用上述配置,打包後的js檔案中
const
定義的變數【沒有】轉換成var宣告的變數 -
使用上述配置,然後webpack配置
targets
中含有低版本的IE,那麼const
定義的變數【會】轉換成var宣告的變數 -
注意
- 上面使用
const
等普通的ES6語法是沒有使用到corejs
;當載入低版本瀏覽器不能識別的類或物件等情況時會使用到corejs
中封裝的程式碼,這樣才能讓低版本瀏覽器識別(比如:Promise)。------corejs只有在下面配置後才起作用
"corejs": "3", "useBuiltIns": "usage"
- 上面使用corejs按需載入後可能還是在IE不能成功執行,因為起打包後生成的js是箭頭函式,IE不支援。babel可以將箭頭函式轉換為瀏覽器識別的函式。上面報錯是因為webpack打包後自帶生成箭頭函式來處理打包後的js,我們可以告訴webpack使用普通函式打包不要使用箭頭函式。
webpack.config.js
配置如下
module.exports = { output: { environment:{ arrowFunction: false } } }
- 上面使用
-