一.TS介紹 1.1 簡介 ts是2012年由微軟開發,在js的基礎上添加了類型支持 1.2 優劣勢 優勢 :任何位置都有代碼提示,增加效率;類型系統重構更容易;使用最新的ECMAscript語法 劣勢:和有些庫的結合併不是很完美;學習需要成本需要理解介面、泛型、類型等知識 1.3 與js區別 首先 ...
一.TS介紹
1.1 簡介
ts是2012年由微軟開發,在js的基礎上添加了類型支持
1.2 優劣勢
優勢 :任何位置都有代碼提示,增加效率;類型系統重構更容易;使用最新的ECMAscript語法
劣勢:和有些庫的結合併不是很完美;學習需要成本需要理解介面、泛型、類型等知識
1.3 與js區別
首先要明確,ts的存在只是為了讓編程更便捷,並不是用來取代js的,是因為js是一個弱類型沒有介面泛型而已。
二.環境安裝
首先安裝ts,直接安裝包即可
註意是全局安裝
然後安裝完後記得初始化ts
初試化完之後有一個ts的配置文件,先修改兩個東西
rootdir表示我們的輸入也就是寫的代碼所在的位置
outdir表示代碼會在此文件輸出
2.1 js的缺陷
有這樣一段js的代碼
當我們運行會發現執行完了第一句就報錯了
原因就不用多說了,這就是js的一個缺陷
這個時候上ts
直接將原代碼放到ts裡面來會發現報錯
這裡提示什麼錯誤用到插件error lens
第一個報錯是我們要把參數規定數據類型
然後發現我們的參數有不符合類型的
所有錯誤清除
註意關鍵步驟來了:
剛纔我們定義了一個代碼所在目錄,需要把ts文件放進去
然後 tsc -watch開啟ts檢測,一旦發現這個ts文件變化就會有輸出文件
可以看到我們的ts文件已經到輸出文件的dist目錄下,並且已經轉換成js文件了
這個時候我們直接運行轉換出來的文件
三.數據類型
3.1 基礎數據類型
首先加一段話
意思表示,如果當我們在src下創建了一些ts文件有命名衝突的時候不加的話就會報錯,加上就相當於添加了一個模塊作用域不會報命名衝突的錯誤
這是ts三種基礎數據類型,數值、布爾、字元串
一定要聲明類型才能夠賦值,而且聲明瞭什麼類型就給什麼值
3.2 數組
數組有幾種定義的方式
首先單獨定義
單獨定義還有一種方式
第二種是混合定義就是可以定義多個類型
跟第一種有點類似,然後用括弧括起來中間用|隔開
最後一種是任意類型
但是並不推薦這種,因為也就失去了ts矯錯的意義
3.3 元祖
用於保存定長長度的數組和數據類型
tuple
首先它的定義
這個時候就定長了,長度固定少一個不行,多一個不行
而且對應位置的數據類型也固定了,不能顛倒
3.4 any與void
首先any表示任意類型,當我們不清楚值的數據類型時可以用any
場景一:
當變數的值會動態改變,比如用戶的輸入時
可以看到我們這裡不論是什麼類型都不會報錯
場景二:
改寫現有代碼時,想要去包含或者是移除類型檢查
可以看到我們並沒有定義這個函數,但是也不會報錯,這個時候用any來移除類型檢查,但是要註意這種方式不太安全
場景三:
定義或存儲各種類型數據的數組
像這樣一個數組會有限制
這樣就不會了
void
某種意義上來說,void與any是相反的,因為他表示沒有任何類型
常常用於當一個函數沒有返回值時
比如這樣一個正常函數是沒有問題的
當我加上了void來聲明後
就會報錯return這一行
刪除後我們才可以正常執行
還有一個點就是當給一個變數聲明為void類型,那麼他的值就只能為undefined和null
為null報錯是以為我們開啟了嚴格模式,需要在ts配置文件中將這一行註釋
3.5 null和undefined
他們的作用就不用多說了
首先他們也是一種數據類型要賦值給變數也要進行定義
但是要註意:在非嚴格模式下,他可以賦值給其他數據類型
3.6 never和object
never類型就是一些總是會拋出異常或者根本就不會有返回值的函數,像這些就可以定義為never類型
object就是定義為一個對象
3.7 枚舉
枚舉是js標準數據類型的一個補充,可以為一組 數值賦予友好的名字
通過enum來定義
這個時候我將一個變數定義為這個類型,
他就只能為這個類型裡面的別名或者說是數值
然後第一個註意點,我給他賦值數值並不會出錯,因為枚舉本身就是為數值取一個好聽的別名,它的本質就是數值
而且他預設就是從0開始的
第二個註意點,雖然預設從0開始,但是我們可以手動修改他的起始值,註意雖然這裡{}包裹,但是裡面是寫為等號賦值
這個時候再去列印
如果修改的是第二個值
如果修改的各自的值
3.8 bigInt和symbol
bigint是用來彌補我們number數據類型最大隻能到2^53-1的整數的缺陷
他的定義方法可以直接在後面加n或者調用bigint這個方法
註意這是es2020新增的類型,所以要將我們的ts轉到2020來
json文件裡面改
symbol的值是唯一的,獨一無二的
並不相等,即使裡面的值都一樣但是他們都為各自的值
3.9 變數聲明與解構
ts的變數聲明解構跟js是一樣的
首先聲明也是:var、let、const
數組解構:
第一種解構
第二種解構,將剩餘的以一個數組存儲
第三種解構,可以取到我們想要的一個位置的數據
對象解構:
3.10 類型斷言
就是手動指定一個值的類型,不再讓js判斷,我說他是什麼就是什麼
兩種方式
第一種方式
<>裡面定義類型外面接變數名
我如果斷言為number,它不具有length,所以就會報錯
第二種方式
通過一個as相當於取別名的方式來定義
應用:
比如現在有個函數,他的參數類型為number或者string,但是number沒有length所以會報錯
我如果給她強制定義為string就不會出現錯誤
3.11 類型別名
就是給一個類型起一個新名字,裡面可有多個數據,都是同一個類型
第一種:
以type開頭聲明,中間用|隔開
定義好後變數用別名來修飾,而且變數只能取定義好的數據,包括數據類型也要相同
第二種:函數
用類型別名聲明瞭一個函數
我要用肯定也要用一個變數,然後用類型別名綁定給他,再去定義我們這個函數
它的作用就是定義好了後,這個函數就只能返回number類型,其他類型都不行
第三種:對象
定義好之後綁定給變數,我們的當前這個屬性就只能用規定好的數據類型了
四.介面
4.1 介面基本使用
介面是一系列抽象方法的聲明,是一些方法特征的集合
interface來定義,跟type很像,但是有區別的,後面會說
定義一個介面
然後我這邊要用同樣是綁定給他,聲明自己的數據
函數的使用
參數採用解構賦值直接拿,然後通過定義好的介面去約束他們,再把函數定義為void類型,也就是沒有返回值
4.2 可選屬性與只讀屬性
在我們定義介面時,某些屬性可以省略我們約束的時候可以不賦值叫做可選屬性,用?修飾
沒有修飾可選屬性,不寫的話會報錯
寫為可選
只讀屬性就是只能讀取,不能修改,readonly來修飾
沒有隻讀屬性時是可以修改的
給到只讀屬性後
我們的const和readonly的區別
因為他們兩個都是不可以修改只能夠讀取
雖然作用大致一樣,但是用處不一樣,一般一般要作為變數使用就是用const來修飾,如果要作為屬性使用就用readonly
4.3 索引簽名
用於描述那些通過索引得到的類型,解決參數問題
當我們定義好介面,如果少一個參數我們可以用可選屬性來將其可要可不要
但是如果多一個參數呢?
三種方法
第一種:不推薦
可以看到我如果直接加在後面會報錯
但是我給一個對象之後再加在後面就不會報錯了
這是因為ts的檢測是淺檢測,我們直接加在後面是一層,但是中間有個對象對象裡面再來一個對象,就屬於深層次了,就檢測不到了,所以這種理論上是不允許的,只是我們投機取巧,不推薦
第二種:
通過類型斷言
我們說過類型斷言,就是我自己來聲明,加上了之後就相當於脫離了ts的校驗規則,你想定義什麼就定義什麼沒有人管得到你了,註意這裡是給這個變數類型斷言,所以只能斷言為people或者any
第三種:
索引簽名
給我們介面添加一個中括弧裡面props是變數名隨便取,第一個string為我們屬性名的類型定義,要註意對象屬性名會自動給你變成字元串,就算你沒添加引號也是字元串,後面則是規定我們值為什麼類型
這樣我們也可以隨便添加任意類型的參數了
4.4 函數介面
函數的介面需要定義一個調用的參數的簽名以及返回值的類型
介面與數組
註意一下我們的介面和數組怎麼來使用,長得很像索引簽名,但其實不是,前面定義的其實是我們數組的下標,所以只能為number類型,後面是數組裡面每一項的值類型
4.5 介面繼承
介面可以繼承介面用到另一個介面上的屬性約束 extends
單繼承:
多繼承:
用逗號隔開
4.6 介面的混合類型
就是可以將介面裡面多個類型混合在一起定義,包括屬性、函數等
因為我們之前都是單獨對對象或者函數進行介面約束,那麼如果要進行一個混合類型介面,以函數為例,先綁定給一個函數
函數裡面先定義好我們的函數,並且提示需要返回值
添加返回值後提示缺少定義好的兩個屬性
直接將counter類型斷言為Counter並將屬性綁定上去
可以看到此時這個counter即為函數又為對象
又可以使用自己函數,又可以調用對象屬性
4.7 介面和類型別名的異同點
主要是兩同兩異
相同一:
都可以描述屬性或者方法
這裡分別用類型別名和介面定義了兩個屬性一個方法,都沒有報錯
應用上去也沒問題
相同二:
都允許擴展
註意類型別名擴展是用&連接
介面的擴展前面有說extends來連接
不同點一:
type可以聲明基本數據類型、聯合類型、數組等等,而介面只能聲明對象,函數也是對象
註意:這是或者的意思,比如在數組那裡有且只有第一個值,有第二個值就會報錯
不同點二:
type不能進行合併,介面可以