第一章 快速入門
0桶良、TypeScript簡介
- TypeScript是JavaScript的超集陨帆。
- 它對JS進行了擴展采蚀,向JS中引入了類型的概念榆鼠,并添加了許多新的特性。
- TS代碼需要通過編譯器編譯為JS识啦,然后再交由JS解析器執(zhí)行颓哮。
- TS完全兼容JS冕茅,換言之腰鬼,任何的JS代碼都可以直接當(dāng)成JS使用熄赡。
- 相較于JS而言彼硫,TS擁有了靜態(tài)類型凌箕,更加嚴(yán)格的語法牵舱,更強大的功能;TS可以在代碼執(zhí)行前就完成代碼的檢查礁凡,減小了運行時異常的出現(xiàn)的幾率顷牌;TS代碼可以編譯為任意版本的JS代碼窟蓝,可有效解決不同JS運行環(huán)境的兼容問題;同樣的功能状共,TS的代碼量要大于JS峡继,但由于TS的代碼結(jié)構(gòu)更加清晰雇卷,變量類型更加明確关划,在后期代碼的維護中TS卻遠遠勝于JS贮折。
1调榄、TypeScript 開發(fā)環(huán)境搭建
-
下載Node.js
安裝Node.js
-
使用npm全局安裝typescript
- 進入命令行
- 輸入:npm i -g typescript
創(chuàng)建一個ts文件
-
使用tsc對ts文件進行編譯
進入命令行
進入ts文件所在目錄
執(zhí)行命令:tsc xxx.ts
2每庆、基本類型
-
類型聲明
類型聲明是TS非常重要的一個特點
通過類型聲明可以指定TS中變量(參數(shù)、形參)的類型
指定類型后伦籍,當(dāng)為變量賦值時帖鸦,TS編譯器會自動檢查值是否符合類型聲明作儿,符合則賦值馋劈,否則報錯
簡而言之,類型聲明給變量設(shè)置了類型变擒,使得變量只能存儲某種類型的值
-
語法:
let 變量: 類型; let 變量: 類型 = 值; function fn(參數(shù): 類型, 參數(shù): 類型): 類型{ ... }
-
自動類型判斷
- TS擁有自動的類型判斷機制
- 當(dāng)對變量的聲明和賦值是同時進行的娇斑,TS編譯器會自動判斷變量的類型
- 所以如果你的變量的聲明和賦值時同時進行的材部,可以省略掉類型聲明
-
類型:
類型 例子 描述 number 1, -33, 2.5 任意數(shù)字 string 'hi', "hi", hi
任意字符串 boolean true苦丁、false 布爾值true或false 字面量 其本身 限制變量的值就是該字面量的值 any * 任意類型 unknown * 類型安全的any void 空值(undefined) 沒有值(或undefined) never 沒有值 不能是任何值 object {name:'孫悟空'} 任意的JS對象 array [1,2,3] 任意JS數(shù)組 tuple [4,5] 元素旺拉,TS新增類型蛾狗,固定長度數(shù)組 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 fullName: 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;
-
unknown
let notSure: unknown = 4; notSure = 'hello';
-
void
let unusable: void = undefined;
-
never
function error(message: string): never { throw new Error(message); }
-
object(沒啥用)
let obj: object = {}; //對象中指定屬性蔼夜,使用的話必須傳入挎扰,如果不想就? let obj: object = {name:string,age?:number}; let b={name:’測試’}; //[propName:string]可以任意屬性 let oj: object = {name:string,[propName:string]:any }; let b={name:’測試’} <!-- 設(shè)置函數(shù)類型的聲明 語法:(形參:類型,形參:類型)=>返回值 --> let d:(a:number,b:number)=>number d=function(a:number,b:number):number=>{ return a+b; }
-
array
let list: number[] = [1, 2, 3]; let list: Array<number> = [1, 2, 3];
-
tuple
let x: [string, number]; x = ["hello", 10];
-
enum
enum Color { Red, Green, Blue, } let c: Color = Color.Green; enum Color { Red = 1, Green, Blue, } let c: Color = Color.Green; enum Color { Red = 1, Green = 2, Blue = 4, } let c: Color = Color.Green;
-
邏輯運算
|:表示類型可以是string或者number
let j:string|number
&:表示類型可以是string又是numberlet j:{name:string}|{age:number} let j={name:’aaa’,age:14}
-類型別名
let k:1|2|3|4|5; type myType=string; let j:myType=’2222’; type myType=1|2|3|4|5; let a=myType;
-
類型斷言
-
有些情況下,變量的類型對于我們來說是很明確官撼,但是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;
-
-
3禁舷、編譯選項
-
自動編譯文件
編譯文件時牵咙,使用 -w 指令后洁桌,TS編譯器會自動監(jiān)視文件的變化侯嘀,并在文件發(fā)生變化時對文件進行重新編譯戒幔。
-
示例:
tsc xxx.ts -w
-
自動編譯整個項目
如果直接使用tsc指令溪食,則可以自動將當(dāng)前項目下的所有ts文件編譯為js文件错沃。
但是能直接使用tsc命令的前提時,要先在項目根目錄下創(chuàng)建一個ts的配置文件 tsconfig.json
tsconfig.json是一個JSON文件玉掸,添加配置文件后司浪,只需只需 tsc 命令即可完成對整個項目的編譯
-
配置選項:
-
include
定義希望被編譯文件所在的目錄
默認(rèn)值:["**/*"]
-
示例:
"include":["src/**/*", "tests/**/*"]
上述示例中啊易,所有src目錄和tests目錄下的文件都會被編譯
-
exclude
定義需要排除在外的目錄
默認(rèn)值:["node_modules", "bower_components", "jspm_packages"]
-
示例:
"exclude": ["./src/hello/**/*"]
上述示例中租谈,src下hello目錄下的文件都不會被編譯
-
extends
定義被繼承的配置文件
-
示例:
"extends": "./configs/base"
上述示例中割去,當(dāng)前配置文件中會自動包含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
編譯選項是配置文件中非常重要也比較復(fù)雜的配置選項
-
在compilerOptions中包含多個子選項咖城,用來完成對編譯的配置
-
項目選項
-
target
設(shè)置ts代碼編譯的目標(biāo)版本
-
可選值:
- ES3(默認(rèn))、ES5滓彰、ES6/ES2015揭绑、ES7/ES2016他匪、ES2017夸研、ES2018亥至、ES2019姐扮、ES2020、ESNext
-
示例:
"compilerOptions": { "target": "ES6" }
如上設(shè)置壤靶,我們所編寫的ts代碼將會被編譯為ES6版本的js代碼
-
lib
指定代碼運行時所包含的庫(宿主環(huán)境)
-
可選值:
- 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
設(shè)置編譯后代碼使用的模塊化系統(tǒng)
-
可選值:
- CommonJS竟终、UMD统捶、AMD喘鸟、System迷守、ES2020、ESNext凯力、None
-
示例:
"compilerOptions": { "module": "CommonJS" }
-
outDir
編譯后文件的所在目錄
默認(rèn)情況下咐鹤,編譯后的js文件會和ts文件位于相同的目錄祈惶,設(shè)置outDir后可以改變編譯后文件的位置
-
示例:
"compilerOptions": { "outDir": "dist" }
設(shè)置后編譯后的js文件將會生成到dist目錄
-
outFile
將所有的文件編譯為一個js文件
默認(rèn)會將所有的編寫在全局作用域中的代碼合并為一個js文件捧请,如果module制定了None疹蛉、System或AMD則會將模塊一起合并到文件之中
-
示例:
"compilerOptions": { "outFile": "dist/app.js" }
-
rootDir
指定代碼的根目錄可款,默認(rèn)情況下編譯后文件的目錄結(jié)構(gòu)會以最長的公共目錄為根目錄闺鲸,通過rootDir可以手動指定根目錄
-
示例:
"compilerOptions": { "rootDir": "./src" }
-
allowJs
- 是否對js文件編譯
-
checkJs
是否對js文件進行檢查
-
示例:
"compilerOptions": { "allowJs": true, "checkJs": true }
-
removeComments
- 是否刪除注釋
- 默認(rèn)值:false
-
noEmit
- 不對代碼進行編譯
- 默認(rèn)值:false
-
sourceMap
- 是否生成sourceMap
- 默認(rèn)值:false
-
-
-
- 嚴(yán)格檢查
- strict
- 啟用所有的嚴(yán)格檢查摸恍,默認(rèn)值為true误墓,設(shè)置后相當(dāng)于開啟了所有的嚴(yán)格檢查
- alwaysStrict
- 總是以嚴(yán)格模式對代碼進行編譯
- noImplicitAny
- 禁止隱式的any類型
- noImplicitThis
- 禁止類型不明確的this
- strictBindCallApply
- 嚴(yán)格檢查bind谜慌、call和apply的參數(shù)列表
- strictFunctionTypes
- 嚴(yán)格檢查函數(shù)的類型
- strictNullChecks
- 嚴(yán)格的空值檢查
- strictPropertyInitialization
- 嚴(yán)格檢查屬性是否初始化
- 額外檢查
- noFallthroughCasesInSwitch
- 檢查switch語句包含正確的break
- noImplicitReturns
- 檢查函數(shù)沒有隱式的返回值
- noUnusedLocals
- 檢查未使用的局部變量
- noUnusedParameters
- 檢查未使用的參數(shù)
- 高級
- allowUnreachableCode
- 檢查不可達代碼
- 可選值:
- true变泄,忽略不可達代碼
- false恼琼,不可達代碼將引起錯誤
- noEmitOnError
- 有錯誤的情況下不進行編譯
- 默認(rèn)值:false
4晴竞、webpack
通常情況下噩死,實際開發(fā)中我們都需要使用構(gòu)建工具對代碼進行打包已维,TS同樣也可以結(jié)合構(gòu)建工具一起使用垛耳,下邊以webpack為例介紹一下如何結(jié)合構(gòu)建工具使用TS飘千。
-
步驟:
-
初始化項目
- 進入項目根目錄护奈,執(zhí)行命令
npm init -y
- 主要作用:創(chuàng)建package.json文件
- 進入項目根目錄护奈,執(zhí)行命令
-
下載構(gòu)建工具
-
npm i -D webpack webpack-cli webpack-dev-server typescript ts-loader clean-webpack-plugin
- 共安裝了7個包
- webpack
- 構(gòu)建工具webpack
- webpack-cli
- webpack的命令行工具
- webpack-dev-server
- webpack的開發(fā)服務(wù)器
- typescript
- ts編譯器
- ts-loader
- ts加載器逆济,用于在webpack中編譯ts文件
- html-webpack-plugin
- webpack中html插件,用來自動創(chuàng)建html文件
- clean-webpack-plugin
- webpack中的清除插件磺箕,每次構(gòu)建都會先清除目錄
- webpack
- 共安裝了7個包
-
-
根目錄下創(chuàng)建webpack的配置文件webpack.config.js
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { CleanWebpackPlugin } = require("clean-webpack-plugin"); module.exports = { optimization:{ minimize: false // 關(guān)閉代碼壓縮,可選 }, entry: "./src/index.ts", devtool: "inline-source-map", devServer: { contentBase: './dist' }, output: { path: path.resolve(__dirname, "dist"), filename: "bundle.js", environment: { arrowFunction: false // 關(guān)閉webpack的箭頭函數(shù)抛虫,可選 } }, resolve: { extensions: [".ts", ".js"] }, module: { rules: [ { test: /\.ts$/, use: { loader: "ts-loader" }, exclude: /node_modules/ } ] }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title:'TS測試' }), ] }
-
根目錄下創(chuàng)建tsconfig.json松靡,配置可以根據(jù)自己需要
{ "compilerOptions": { "target": "ES2015", "module": "ES2015", "strict": true } }
-
修改package.json添加如下配置
{ ...略... "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack", "start": "webpack serve --open chrome.exe" }, ...略... }
在src下創(chuàng)建ts文件,并在并命令行執(zhí)行
npm run build
對代碼進行編譯建椰,或者執(zhí)行npm start
來啟動開發(fā)服務(wù)器
-
5雕欺、Babel
-
經(jīng)過一系列的配置,使得TS和webpack已經(jīng)結(jié)合到了一起屠列,除了webpack,開發(fā)中還經(jīng)常需要結(jié)合babel來對代碼進行轉(zhuǎn)換以使其可以兼容到更多的瀏覽器伞矩,在上述步驟的基礎(chǔ)上笛洛,通過以下步驟再將babel引入到項目中。
-
安裝依賴包:
npm i -D @babel/core @babel/preset-env babel-loader core-js
- 共安裝了4個包乃坤,分別是:
- @babel/core
- babel的核心工具
- @babel/preset-env
- babel的預(yù)定義環(huán)境
- @babel-loader
- babel在webpack中的加載器
- core-js
- core-js用來使老版本的瀏覽器支持新版ES語法
- @babel/core
-
修改webpack.config.js配置文件
...略... module: { rules: [ { test: /\.ts$/, use: [ { loader: "babel-loader", options:{ presets: [ [ "@babel/preset-env", { "targets":{ "chrome": "58", "ie": "11" }, "corejs":"3", "useBuiltIns": "usage" } ] ] } }, { loader: "ts-loader", } ], exclude: /node_modules/ } ] } ...略...
如此一來苛让,使用ts編譯后的文件將會再次被babel處理,使得代碼可以在大部分瀏覽器中直接使用湿诊,可以在配置選項的targets中指定要兼容的瀏覽器版本狱杰。
-