TypeScript的應用方式

> 本文不講如何安裝,只講代碼中的實際應用

# 一、什么是 TypeScript?

typescript是js的超集,它在js的基礎上增加了靜態類型校驗,可以在運行前校驗js中的一些錯誤并修正。

在定義類型之后,js中任何地方都會有文檔提示,對象中包含的值都可以提示出來,這一點讓js變得相當友好。

那么想要在已有項目中增加ts需要怎么做?

ts支持漸進式遷移,可配置只檢查部分文件,在已有項目中慢慢改造。ts的類型檢查不會影響js代碼的執行、這意味著,即便類型校驗有錯誤,代碼依舊運行良好。

ts的困難在于它需要定義所有的值類型,這個工作量還是蠻大的。

# 二、ts的簡單使用

**ts的類型定義語法如下**

- 基礎類型:

```javascript

let isDone: Boolean = false;

let str: String = '';

let count: Number = 1;

// 使用聯合操作符

let some1: Number | String = 1;

let some2: Number | String = '1';

```

- 數組

```javascript

let arr1: number[] = [1,2];

let arr2: Array<string> = ['1','2']; // 泛型寫法,下面會講

let arr3: [string,boolean] = ['1',false]; // 元組-定義已知數量和類型

```

- 對象(當存在復雜對象時,使用接口和類來聲明,后面會講)

```javascript

let obj: {a: string, b: number } = {a: '我是字符串',b: 2};

```

- any

```javascript

let something: any = 'asd';

```

any用來表示任何類型,ts不會對它進行校驗。

>? 如果你的ts代碼中到處都是any,建議不要使用ts更方便些。

- viod、null、undefined、never

這些值基本沒什么用,有興趣可以自己查看[文檔](https://www.tslang.cn/docs/handbook/basic-types.html)

- 枚舉 **enum**

**enum**類型是對JavaScript標準數據類型的一個補充。 使用枚舉類型可以為一組數值賦予友好的名字。

```javascript

enum Color {Red, Green, Blue} // 默認情況下,從0開始為元素編號。

let c: Color = Color.Green; // => 1

//你也可以手動的指定成員的數值。 例如,我們將上面的例子改成從 1開始編號:

enum Color {Red = 1, Green, Blue}

let c: Color = Color.Green; // => 2

```

它不但可以使用key獲取value,還可以使用value獲取key。

```javascript

enum Color {Red=1, Green, Blue}

let colorName: string = Color[2]; // => 'Green'

```

# 三、ts進階使用

## 類型斷言

當你確定某個值的類型時,你可以指定它的類型。它有兩種寫法:

尖括號寫法

```javascript

let someValue: any = "this is a string"; // any未知類型

let str: string = someValue; // error someValue不是string類型

// 斷言為string,校驗成功

let str: string = <string>someValue;

```

as寫法

```javascript

let someValue: any = "this is a string";

let str: string = someValue as string

```

## 接口interface

interface用來定義復雜類型(對象、函數、索引類型等)

```javascript

interface Config {

? readonly color: string; // 定義只讀

? width?: number; // 定義可選屬性

}

function doSome( option: Config ){

? // option.color

? // option.width

}

```

同一作用域中同名的interface會自動合并

```javascript

interface Config {

? color: string;

? width: number;

}

// 同一作用域中

interface Config {

? height: number;

}

// 會合并為

interface Config {

? color: string;

? width: number;

? height: number;

}

```

extentds (interface可以使用extentds進行拓展)

```javascript

interface Parent{

? readonly color: string; // 可定義常量

? width: number;

}

interface Children extends Parent{

? height: number;

}

```

## 類

公共,私有 與 存取

1、public

```javascript

class Animal {

? ? name: string; // 默認為public

? ? public id: string; // 也可以標明public

}

```

2、private

```javascript

class Animal {

? ? // private 禁止在類的外部訪問

? ? private move() {

// dosomething

? ? }

}

new Animal().move; // 錯誤: 'move' 是私有的.

```

3、get、set

TypeScript支持通過getters/setters來截取對對象成員的訪問。與vue的watcher同理。

```javascript

class Animal {

? ? get fullName(): string {

? ? ? ? return this._fullName;

? ? }

? ? set fullName(newName: string) {

? ? ? ? // dosomething

? ? }

}

```

4、readonly標明只讀

```javascript

class Animal {

? ? readonly number: number = 8;

}

```

還有static、protected等,這里不過多說明,詳情請看[文檔。](https://www.tslang.cn/docs/handbook/classes.html)

## 函數

函數類型包含兩部分:參數類型和返回值類型。

```javascript

// :number 表示返回值為number

function add(x: number, y: number): number {

? ? return x + y;

}

let myAdd = function(x: number, y: number): number { return x + y; };

```

聲明一個未賦值函數

```javascript

let fn: (x: number, y: number) => number;

fn = myAdd;

```

除此之外,interface同樣可以聲明函數類型

```javascript

// : boolean表示返回值為布爾值

interface Func {

? (source: string, subString: string): boolean;

}

// 命名為x,y或者其他都可以

let ff: Func = (x: string, y: string): boolean => {

return x === y

}

```

函數參數類型只會校驗它的類型,不會校驗它的名字

## type類型別名

類型別名會給一個類型起個新名字。它可以作用于原始值,聯合類型,元組以及其它任何你需要手寫的類型。它的語法看起來像是普通的js。

```java

// 給String重新命名

type Easing = String

// 定義聯合類型

type Easing = 'a' | 'b' | 'c'

```

type可以將多個interface聯合或者交叉

```java

interface A{

? ? kind: "square";

? ? size: number;

}

interface B{

? ? kind: "rectangle";

? ? width: number;

? ? height: number;

}

interface C{

? ? kind: "circle";

? ? radius: number;

}

type Shape1 = A | B | C; // 聯合

type Shape2 = A & B & C; // 交叉

```

type也可以聲明函數和元組

```java

// 函數

type Easing = () => string

// 元組

type DudeType = {

? [key in Keys]: string // keys是一個索引類型

}

```

> type和interface功能類似,但type更像一個值而不是一個類型。在兩者都能實現需求的情況下,官方建議優先使用interface。

# 四、ts高級用法--泛型

考慮到代碼的可重用性和拓展性,ts允許使用泛型來定義未知類型,使用尖括號語法。

```javascript

// 當入參未知時,我們可定義一個泛型

function identity<T>(arg: T): T {

? ? return arg;

}

// 它可以這樣用,表示數組

function identity<T>(arg: T[]): T[] {

? ? return arg;

}

// 或者表示對象

function identity<T>(arg: {x: T, y: T}): T {

? ? return arg.x;

}

```

泛型支持extends語法

```javascript

interface Lengthwise {

? ? length: number;

}

function loggingIdentity<T extends Lengthwise>(arg: T): T {

? ? console.log(arg.length);? // 可以用時length屬性

? ? return arg;

}

```

泛型promise使用示例

```typescript

// Promise<T>表示Promise.resolve的值類型是T

// catch類型默認是any

let ajax = <T>(params: any): Promise<T> => {

? return new Promise((resolve) => {

? ? axios.get('/list').then(res=> {

? ? ? resolve(params)

? ? })

? })

}

// 使用時

ajax<{a: string,b:number}>(params).then(res=>{

? ? // res 類型為{a: string,b:number}

)

```

>此處只講了typescript的一些常見用法和問題,更多說明請看官方文檔。[(中文文檔3.1](https://www.tslang.cn/docs/release-notes/typescript-3.1.html),[英文文檔4.1)](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-1.html)

==一些運算操作符==

1. !斷言此處有值。

```javascript

let y!:number = 1; // 表示y必定有值

```

2. ?表示可能未定義。

```javascript

let obj = {

? ? y?: number, // 相當于? number | undefined

? ? z: string

}

let num: number;

num = obj.y; // error,不能將類型“number | undefined”分配給類型“number”。

```

3. ?? 空值合并。

通常我們取一個可能存在的值時,會像這樣

```javascript

let obj = {

? ? y?: number

}

let num: number;

num = obj.y || 1;

```

但當obj.y為0時,它會存在問題。所以ts提供了更好的解決方案。??只會判斷null和undefined兩個值。

```javascript

let obj = {

? ? y?: number

}

let num: number;

num = obj.y ?? 1; // 即使y為0,也會得到0,而不是1

```

4.!取值用法和?的賦值用法。

!表示必定有值,?表示可能有值,所以他們也可以這樣使用

當你確定值必定存在時

```javascript

let obj: {

? ? a?: {

? ? ? ? ? b?: number

}

} = { a: { b: 1 } };

let x: number = obj.a.b; // 報錯,對象可能未定義

let y: number = obj!.a!.b; // 通過

```

當你不確定值是否存在

```javascript

let obj: {

? ? ? a?: {

? ? ? ? b?: number

? ? ? }

? ? }

obj.a.b = 1; // 報錯

obj?.a?.b = 1; // 通過

```

5. !(放在value之后)允許null和undefined

```javascript

let y:number

y = null // 無法通過編譯

y = undefined // 無法通過編譯

y = null!? ? ? // 通過

y = undefined! // 通過

```

6. 最新特性??=、||=、&&=?

有時候我們需要對可能存在的值給一個默認值

```javascript

let obj = {

? ? y?: number

}

// 正常情況

obj.y = obj.y ? obj.y : 1;

// 使用??空值合并

obj.y = obj.y ?? 1;

// 使用??=運算符,他看起來有點像 +=和-=

obj.y ??= 1;

```

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,673評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,668評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,004評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,173評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,705評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,426評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,656評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,833評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,371評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,621評論 2 380

推薦閱讀更多精彩內容