[TOC] #### 1. TypeScript 是什么 ? --- **編程語言的類型: 靜態(tài)類型語言、動態(tài)類型語言** 靜態(tài)類型語言的數(shù)據(jù)類型是在編譯期間檢查的。也就是說,在編寫程序時就要聲明變量的數(shù)據(jù)類型。如: Java 動態(tài)類型語言是指在運(yùn)行期間才去做數(shù)據(jù)類型檢查的語言。也就是說,永遠(yuǎn)不用給變量指定數(shù)據(jù)類型。如: Python、PHP **TypeScript 究竟是什么 ?** typescript 官網(wǎng): [https://typescriptlang.org](https://typescriptlang.org) TypeScript 是 Type 和 JavaScript 的結(jié)合,TypeScript 就是將不看重類型的動態(tài)語言 JavaScript,變成關(guān)注類型的靜態(tài)語言 #### 2. 為什么要學(xué)習(xí) TypeScript ? --- **程序更容易理解** ts 可以約定函數(shù)或方法輸入輸出的參數(shù)類型,外部條件等 **效率更高** 在不同的代碼塊和定義中進(jìn)行跳轉(zhuǎn)、代碼補(bǔ)全、接口提示 **更少的錯誤** 編譯期間能夠發(fā)現(xiàn)大部分錯誤,杜絕一些比較常見的錯誤 #### 3. 安裝 TypeScript --- 全局安裝 typescript ```bash npm install -g typescript ``` 查看版本 ```bash tsc -V ``` 創(chuàng)建 helloworld.ts ```javascript const hello = (name: string) => { } ``` 編譯 ```bash tsc helloworld.ts ``` 補(bǔ)充: 命令行運(yùn)行 ts 文件需要安裝 ts-node 包 ```sh npm install -g ts-node ``` 然后就可以使用 ts-node 命令運(yùn)行 ts 文件了 ```sh ts-node helloworld.ts ``` #### 4. 原始數(shù)據(jù)類型和 any 類型 --- 最新的 ESMAScript 標(biāo)準(zhǔn)定義了八種數(shù)據(jù)類型 七種原始數(shù)據(jù)類型: number、string、boolean、undefined、null、BigInt、Symbol。另外一種是 Object 注意: undefined、null 是所有類型的子類型,所以下面寫法是正確的 ```javascript let age: number = undefined ``` 頂級類型: any,可以接收所有數(shù)據(jù)類型的數(shù)據(jù) ```javascript let all: any = null; all = true; all = 123456; all = 'liang'; ``` #### 5. 數(shù)組和元組(tuple) --- 聲明一個 number 類型的數(shù)組,數(shù)組元素必須為 number 類型 ```javascript let numArr: number[] = [1, 2, 3] ``` 元組: 給數(shù)組元素分別指定數(shù)據(jù)類型 ```javascript // 定義元組時,數(shù)組元素個數(shù)不能超過聲明的類型個數(shù) let user: [string, number] = ['liang', 23] // 但可以追加數(shù)組元素,追加的數(shù)據(jù)類型必須在聲明的類型中,也就是 string, number user.push(10) ``` #### 6. Interface 接口 --- Interface 不是 JavaScript 中的概念,而是 ts 作類型檢查用的,所以 ts 在編譯后,Interface 是不會被轉(zhuǎn)譯過去的 interface 描述對象類型 ```javascript // 定義接口 interface Person { // 只讀屬性 readonly id: number, // 必須屬性 name: string, // 可選屬性 age?: number, } // 變量使用接口 let user: Person = { id: 1, name: "liang", // age: 23, // 可選屬性,定義不定義都可以 // like: "code", // 對象文字可以只指定已知屬性,但 “like”不在接口“Person”中 } // user.id = 2 // 報(bào)錯: 因?yàn)?id 是只讀屬性, 無法修改 ``` #### 7. 函數(shù)中聲明數(shù)據(jù)類型 --- 普通的聲明函數(shù),函數(shù)的結(jié)果返回 number 類型 ```javascript /** * 可選參數(shù)z: 省略時為 undefined */ function add(x: number, y: number, z?: number): number { if (typeof z === 'number') { return x + y + z } else { return x + y } } ``` 函數(shù)表達(dá)式聲明的函數(shù)返回的是一個函數(shù)類型 ![](https://img.itqaq.com/art/content/330a4854424aee2bbd1cf3733a3d8257.png) ```javascript const add = (x: number, y: number, z?: number): number => { if (typeof z === 'number') { return x + y + z } else { return x + y } } // 在 ts 中 : 后面都是在聲明類型,和實(shí)際代碼邏輯無關(guān) let abc: (x: number, y: number, z?: number) => number = add // interface 描述函數(shù)類型 interface ISum { (x: number, y: number, z?: number): number } let def: ISum = add ``` #### 8. 類型推論 (type inference) --- 官方文檔: [https://www.typescriptlang.org/docs/handbook/type-inference.html](https://www.typescriptlang.org/docs/handbook/type-inference.html) 當(dāng)我們把數(shù)據(jù)賦給變量時,沒有指定數(shù)據(jù)類型,ts 會自動推測出一個類型,如下圖: ![](https://img.itqaq.com/art/content/a6cd4cf6961def297e16174e37443641.png) 因?yàn)?ts 已經(jīng)將變量 x 的類型推斷為 number,那么當(dāng)我們給變量 x 賦值一個 string 類型的數(shù)據(jù)則會提示錯誤 ![](https://img.itqaq.com/art/content/c47d202809f4e96be7e204b1dc2bc947.png) #### 9. 聯(lián)合類型 --- ```javascript // 聯(lián)合類型 union types let numOrString: number | string numOrString.toString() // toString() 是 number|string 的共有方法 // numOrString.length // 報(bào)錯: length 不是共有屬性, string 有,但 number 沒有 ``` #### 10. 泛型 Generics --- 基礎(chǔ)使用 ```javascript function echo<T>(arg: T): T { return arg } const str: string = 'liang' const num: number = 123456 console.log(str, num); ``` 交換數(shù)組中兩個元素的位置 ```javascript function swap<T, U>(tuple: [T, U]): [U, T] { return [tuple[1], tuple[0]] } const res1 = swap(['123', 456]) console.log(res1); ``` 約束泛型 ```javascript interface ILength { length: number } // 約束泛型 function echoWithArr<T extends ILength>(args: T): T { console.log(args.length); return args } echoWithArr('12345') echoWithArr(['1', 2]) echoWithArr({width: 10, length: 30}) ``` #### 11. 類型別名 ---- 類型別名的作用: 復(fù)雜的類型名簡單化 ```javascript // 普通方式 let sum: (x: number, y: number) => number const result1 = sum(1, 2) // 類型別名 // 語法格式: type 別名 = 全名 type PulsType = (x: number, y: number) => number let sum2: PulsType const result2 = sum2(1, 2) // 聯(lián)合類型的別名 type strOrNum = string | number let data3: strOrNum data3 = 23 data3 = 'liang' // data3 = true // 報(bào)錯 ``` #### 12. 字面量 ---- ```javascript const str: 'name' = 'name' // const str: 'name' = 'name2' // 報(bào)錯 const number: 1 = 1 type Directions = 'Up' | 'Down' | 'Left' | 'Right' let toWhere: Directions = 'Left' ``` #### 13. 交叉類型 ```javascript interface IName { name: string } type IPerson = IName & {age: number} let person: IPerson = {name: 'liang', age: 23} ```