TypeScript的應(yīng)用方式

> 本文不講如何安裝,只講代碼中的實(shí)際應(yīng)用

# 一、什么是 TypeScript?

typescript是js的超集,它在js的基礎(chǔ)上增加了靜態(tài)類型校驗(yàn),可以在運(yùn)行前校驗(yàn)js中的一些錯(cuò)誤并修正。

在定義類型之后,js中任何地方都會(huì)有文檔提示,對(duì)象中包含的值都可以提示出來,這一點(diǎn)讓js變得相當(dāng)友好。

那么想要在已有項(xiàng)目中增加ts需要怎么做?

ts支持漸進(jìn)式遷移,可配置只檢查部分文件,在已有項(xiàng)目中慢慢改造。ts的類型檢查不會(huì)影響js代碼的執(zhí)行、這意味著,即便類型校驗(yàn)有錯(cuò)誤,代碼依舊運(yùn)行良好。

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

# 二、ts的簡(jiǎn)單使用

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

- 基礎(chǔ)類型:

```javascript

let isDone: Boolean = false;

let str: String = '';

let count: Number = 1;

// 使用聯(lián)合操作符

let some1: Number | String = 1;

let some2: Number | String = '1';

```

- 數(shù)組

```javascript

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

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

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

```

- 對(duì)象(當(dāng)存在復(fù)雜對(duì)象時(shí),使用接口和類來聲明,后面會(huì)講)

```javascript

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

```

- any

```javascript

let something: any = 'asd';

```

any用來表示任何類型,ts不會(huì)對(duì)它進(jìn)行校驗(yàn)。

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

- viod、null、undefined、never

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

- 枚舉 **enum**

**enum**類型是對(duì)JavaScript標(biāo)準(zhǔn)數(shù)據(jù)類型的一個(gè)補(bǔ)充。 使用枚舉類型可以為一組數(shù)值賦予友好的名字。

```javascript

enum Color {Red, Green, Blue} // 默認(rèn)情況下,從0開始為元素編號(hào)。

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

//你也可以手動(dòng)的指定成員的數(shù)值。 例如,我們將上面的例子改成從 1開始編號(hào):

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進(jìn)階使用

## 類型斷言

當(dāng)你確定某個(gè)值的類型時(shí),你可以指定它的類型。它有兩種寫法:

尖括號(hào)寫法

```javascript

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

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

// 斷言為string,校驗(yàn)成功

let str: string = <string>someValue;

```

as寫法

```javascript

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

let str: string = someValue as string

```

## 接口interface

interface用來定義復(fù)雜類型(對(duì)象、函數(shù)、索引類型等)

```javascript

interface Config {

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

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

}

function doSome( option: Config ){

? // option.color

? // option.width

}

```

同一作用域中同名的interface會(huì)自動(dòng)合并

```javascript

interface Config {

? color: string;

? width: number;

}

// 同一作用域中

interface Config {

? height: number;

}

// 會(huì)合并為

interface Config {

? color: string;

? width: number;

? height: number;

}

```

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

```javascript

interface Parent{

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

? width: number;

}

interface Children extends Parent{

? height: number;

}

```

## 類

公共,私有 與 存取

1、public

```javascript

class Animal {

? ? name: string; // 默認(rèn)為public

? ? public id: string; // 也可以標(biāo)明public

}

```

2、private

```javascript

class Animal {

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

? ? private move() {

// dosomething

? ? }

}

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

```

3、get、set

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

```javascript

class Animal {

? ? get fullName(): string {

? ? ? ? return this._fullName;

? ? }

? ? set fullName(newName: string) {

? ? ? ? // dosomething

? ? }

}

```

4、readonly標(biāo)明只讀

```javascript

class Animal {

? ? readonly number: number = 8;

}

```

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

## 函數(shù)

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

```javascript

// :number 表示返回值為number

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

? ? return x + y;

}

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

```

聲明一個(gè)未賦值函數(shù)

```javascript

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

fn = myAdd;

```

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

```javascript

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

interface Func {

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

}

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

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

return x === y

}

```

函數(shù)參數(shù)類型只會(huì)校驗(yàn)它的類型,不會(huì)校驗(yàn)它的名字

## type類型別名

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

```java

// 給String重新命名

type Easing = String

// 定義聯(lián)合類型

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

```

type可以將多個(gè)interface聯(lián)合或者交叉

```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; // 聯(lián)合

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

```

type也可以聲明函數(shù)和元組

```java

// 函數(shù)

type Easing = () => string

// 元組

type DudeType = {

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

}

```

> type和interface功能類似,但type更像一個(gè)值而不是一個(gè)類型。在兩者都能實(shí)現(xiàn)需求的情況下,官方建議優(yōu)先使用interface。

# 四、ts高級(jí)用法--泛型

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

```javascript

// 當(dāng)入?yún)⑽粗獣r(shí),我們可定義一個(gè)泛型

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

? ? return arg;

}

// 它可以這樣用,表示數(shù)組

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

? ? return arg;

}

// 或者表示對(duì)象

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);? // 可以用時(shí)length屬性

? ? return arg;

}

```

泛型promise使用示例

```typescript

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

// catch類型默認(rèn)是any

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

? return new Promise((resolve) => {

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

? ? ? resolve(params)

? ? })

? })

}

// 使用時(shí)

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

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

)

```

>此處只講了typescript的一些常見用法和問題,更多說明請(qǐng)看官方文檔。[(中文文檔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)

==一些運(yùn)算操作符==

1. !斷言此處有值。

```javascript

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

```

2. ?表示可能未定義。

```javascript

let obj = {

? ? y?: number, // 相當(dāng)于? number | undefined

? ? z: string

}

let num: number;

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

```

3. ?? 空值合并。

通常我們?nèi)∫粋€(gè)可能存在的值時(shí),會(huì)像這樣

```javascript

let obj = {

? ? y?: number

}

let num: number;

num = obj.y || 1;

```

但當(dāng)obj.y為0時(shí),它會(huì)存在問題。所以ts提供了更好的解決方案。??只會(huì)判斷null和undefined兩個(gè)值。

```javascript

let obj = {

? ? y?: number

}

let num: number;

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

```

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

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

當(dāng)你確定值必定存在時(shí)

```javascript

let obj: {

? ? a?: {

? ? ? ? ? b?: number

}

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

let x: number = obj.a.b; // 報(bào)錯(cuò),對(duì)象可能未定義

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

```

當(dāng)你不確定值是否存在

```javascript

let obj: {

? ? ? a?: {

? ? ? ? b?: number

? ? ? }

? ? }

obj.a.b = 1; // 報(bào)錯(cuò)

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

```

5. ?。ǚ旁趘alue之后)允許null和undefined

```javascript

let y:number

y = null // 無法通過編譯

y = undefined // 無法通過編譯

y = null!? ? ? // 通過

y = undefined! // 通過

```

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

有時(shí)候我們需要對(duì)可能存在的值給一個(gè)默認(rèn)值

```javascript

let obj = {

? ? y?: number

}

// 正常情況

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

// 使用??空值合并

obj.y = obj.y ?? 1;

// 使用??=運(yùn)算符,他看起來有點(diǎn)像 +=和-=

obj.y ??= 1;

```

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容