【TS】快速上手(二)型別宣告

語言: CN / TW / HK

theme: fancy highlight: tomorrow-night-blue


嗨!~ 大家好,我是YK菌 🐷 ,一個微系前端 ✨,愛思考,愛總結,愛記錄,愛分享 🏹,歡迎關注我呀 😘 ~ [微訊號: yk2012yk2012,微信公眾號:ykyk2012]

「這是我參與11月更文挑戰的第25天,活動詳情檢視:2021最後一次更文挑戰

今天來介紹typescript的型別系統,主要是學習一些語法

參考連結:

  • 官網:https://www.typescriptlang.org/
  • 中文網:https://www.tslang.cn/ (貌似很久沒維護了)
  • 掘金小冊: https://juejin.cn/book/6844733813021491207
  • 書籍:《深入理解TypeScript》 https://jkchao.github.io/typescript-book-chinese/
  • B站尚矽谷影片:https://www.bilibili.com/video/BV1Xy4y1v7S2

1. 起步

  • 型別宣告是TS非常重要的一個特點
  • 通過型別宣告可以指定TS中變數(引數、形參)的型別
  • 指定型別後,當為變數賦值時,TS編譯器會自動檢查值是否符合型別宣告,符合則賦值,否則報錯
  • 簡而言之,型別宣告給變數設定了型別,使得變數只能儲存某種型別的值

我們先來看看,TypeScript給變數指定型別的語法(型別註解)是什麼

```ts // 宣告一個變數 let 變數: 型別

// 宣告一個變數並給其賦值 let 變數: 型別 = 值

// 宣告一個函式 function yk(引數: 引數型別): 函式返回值型別{ //... } ``` 這裡我們可以看到,就是在變數後面就一個冒號,然後標識其型別就可以了

2. 型別

下面我們就來介紹介紹,TypeScript中到底有哪些型別

學過js你認識的型別:booleannumberstringundefinednullsymbolbigintobject

你可能不認識的型別:voidanyunknownnever

我們後面會詳細的介紹這些你可能不認識的型別

## 2.1 變數

如果我們在宣告變數指定型別後,之後如果給變數賦值為其他型別的值,編輯器會報錯,如圖所示

ts let n: number = 1 n = 3 n = '1' // 編輯器報錯,不能將字串賦值給number型別的變數

image.png

2.2 自動型別判斷

  • TS擁有自動的型別判斷機制
  • 當對變數的宣告和賦值是同時進行的,TS編譯器會自動判斷變數的型別
  • 所以如果你的變數的宣告和賦值時同時進行的,可以省略掉型別宣告

image.png

那都可以省略了,還要自己寫型別幹嘛呢? 事實上,顯式的寫型別更有優勢的地方是在函式定義的時候

2.3 函式

我們先回顧下用js宣告一個函式的特點:js中的函式是不考慮引數的型別個數

```js function sum(a, b){ return a + b }

console.log(sum(1, 2)) // 3

console.log(sum(1, '2')) // '12' ```

而用ts定義

```ts function sum(a: number, b: number): number{ return a + b }

console.log(sum(1, 2)) // 3 ```

image.png

引數數量也有限制

image.png

2.4 型別詳解

基本型別我們就不詳細談了,我們來說說TS中一些特殊的型別

void

相信熟悉Java或者C的同學應該對void也不會陌生,當函式沒有返回值的時候,定義函式的返回值型別就是void

其實我們知道,在JavaScript中,如果定義一個函式不寫返回值,那麼它預設是返回 undefined 的~

什麼都不返回 js function fn(): void { } 只寫一個return

js function fn(): void { return } 返回一個undefined

js function fn(): void { return undefined }

我們返回一個null也是可以的

js function fn(): void { return null }

除了以上的幾種情況,其他情況都是不行的

image.png

image.png

也就是說只有nullundefined可以賦給void

any

any 表示的是任意型別,一個變數設定型別為 any 後,相當於對該變數關閉了TS的型別檢測。

隱式any:如果只宣告變數不指定型別不給變數賦值,變數就是any型別的

當把any型別的變數可以賦值給其他型別的變數,不會報錯

```ts let a let b: any a = 1 a = '1' b = '1' b = 1

let c:string = '123' c = b ```

any型別是多人協作專案的大忌,很可能把Typescript變成AnyScript,通常在不得已的情況下,不應該首先考慮使用此型別。

unknown

開發的時候有些變數就是事先不知道的型別怎麼辦呢?可以使用unknown

unknownany的區別就是,將unknown型別變數賦值給其他任意型別的變數時,會報錯

image.png

可以這樣理解:unknown型別的變數就是型別安全的any,不能直接賦值給其他型別的變數

需要在賦值之前做好型別判斷 (這叫縮小類型範圍)

ts if (typeof b === 'string') { c = b }

或者這樣寫 【型別斷言】(相當於告訴解析器b就是一個string型別的變數)

ts c = b as string

ts c = <string>b

never

never 表示永遠不會返回結果

js function fn(): never{ throw new Error('報錯了!') }

物件

image.png

一般來說,我們對於物件的型別檢查一般是檢查物件中有哪些屬性,屬性是什麼型別。

可以用{} 來指定物件中可以包含哪些屬性 語法:{屬性名: 屬性型別, ...}

image.png

屬性多了少了都不行

image.png

可選屬性,在屬性名後面加一個 ?

ts let obj: {name: string, age?: number} obj = {name: 'yk', age: 18} obj = {name: 'yk'}

如果後續屬性不確定叫什麼名字,也不確定是什麼型別,那麼可以這樣寫[propName: string]: unknown

```ts // 定義物件結構 let obj: { name: string, [propName: string]: unknown }

obj = {name: 'yk', age: 18, gender: 'male'} ```

函式

因為function是關鍵字,所有這裡用Function來宣告函式

js let fn: Function

image.png

和物件一樣,我們一般會限制函式有幾個引數,引數的型別,返回值的型別,所以就可以以一種類似箭頭函式的方式來宣告一個函式型別的變數

ts // 定義函式結構 let fn: (a: number, b: number) => number

image.png

陣列

比較常用的就是這種方式: 在元素型別後面接上 []: ts let arr: number[] = [1, 2, 3] let arr2: string[] = ['y', 'k']

還有一種是使用泛型:

ts let list: Array<number> = [1, 2, 3] let list2: Array<string> = ['y', 'k']

元組 Tuple

元組是TS新出的型別,表示固定長度的array

元組中包含的元素,必須與宣告的型別一致,而且不能、不能,甚至順序都不能不一樣

image.png

image.png

字面量

也可以使用字面量去指定變數的型別,這相當於給他設定成了一個常量

js let a: 10 a = 10

image.png

2.5 聯合型別

可以給一個變數定義一個聯合型別,型別名之間用 | 隔開

這個時候,字面量型別就有用了 ts let gender : "male" | "female"

此時gender只能被賦值成兩個值

2.6 類型別名

這個時候,如果一個型別的字面量型別選擇過多,重複編寫就比較麻煩,這就可以使用類型別名

```ts type myType = 1 | 2 | 3 | 4 | 5 let i: myType let j: myType let k: myType

k = 2 ```

image.png

2.7 總結

image.png

3. 型別斷言

有些情況下,變數的型別對於我們來說是很明確,但是TS編譯器卻並不清楚,此時,可以通過型別斷言來告訴編譯器變數的型別,斷言有兩種形式:

第一種

ts let someValue: unknown = "this is a string"; let strLength: number = (someValue as string).length;

第二種

ts let someValue: unknown = "this is a string"; let strLength: number = (<string>someValue).length;

最後,歡迎關注我的專欄,和YK菌做好朋友

「其他文章」