12.TypeScript徹底解讀-高級類型(1)css
高級類型中文網的地址:https://typescript.bootcss.com/advanced-types.htmlhtml
建立新的測試文件es6
index.ts內引入typescript
交叉類型
交叉類型就是取多個類型的並集npm
Object.assign就是合併兩個對象,包含兩個對象各有的屬性,合成一個總的對象json
定義的函數也是接收兩個對象,最後返回兩個對象合併後的結果。數組
返回值裏既包含arg1,也包含了arg2的屬性dom
因此返回的類型就能夠用交叉類型來返回: T & U函數
res是個數組因此這裏返回res確定是不對的。測試
這裏須要使用類型斷言
調用這個方法傳進去兩個對象,最終返回的是兩個對象合併後的對象,因此這裏再經過點.就能夠把a和b這兩個屬性都點出來了
這就是交叉類型,能夠理解爲與的一個操做
聯合類型
這樣就表示當前這個類型幾課時type1也能夠是type2還能夠是type3,只要是其中的一種就能夠
這裏先判斷是不是string類型,若是是stirng類型就返回它的length,若是不是string類型,就先tostring 一下而後再返回它的的length
那麼這裏既能夠是stirng類型,也能夠是number類型
傳入布爾類型那麼就會報錯了。這就是聯合類型
類型保護
ts在編譯階段就會幫咱們監察錯誤,有些數據只有在代碼運行以後才能知道結果
Math.random()是0到1的隨機數,乘以10就是0到10的
item的值是隨即的不固定的,這個值在編譯階段是沒法肯定是哪一個類型的值的
因此有時候就須要先判斷他的類型
這裏判斷item的length,length屬性是stirng類型纔有的,若是是string類型就返回它的length,若是是number類型那麼就返回它的toFixed方法。可是這裏報錯了
報的錯誤
咱們選中getRandomValue方法代碼塊。看到它返回的是一個stirng或者number的聯合類型。
這裏的itme也是stirng或者是number類型,這段邏輯在js是沒有問題的 可是在ts中是有問題的,它會監測item的類型,
因此這個時候咱們就要用到類型保護
若是不用類型保護的話,也可使用類型斷言,這個地方有個缺點,就是多個地方只要用到這個item的地方就要使用類型斷言
因此咱們可使用類型保護
返回值的類型是value is string。看上去像是一句話。用is表示返回值的類型
把鼠標放到item上看一下,這裏已經判斷出了這是一個stirng類型。就是經過類型保護ts知道了item是一個stirng類型,那麼if代碼塊裏面的item都是一個stirng類型
既然你的值要麼是numer要麼是string類型,if是string類型了。 那麼else裏面自動判斷出是number類型的.這個要比類型斷言使用起來方便多了。可是上面多定義了一個函數
函數裏面咱們就定義了一個判斷,是不用定義一個函數這麼複雜的,定義函數去判斷適合邏輯比較複雜的類型的判斷
這裏簡單的類型判斷,咱們可使用第二種方式typeof
typeof在js裏面是有這個關鍵詞的,能夠判斷值的類型
在ts中 會把typeof item當作一個類型保護。可是這個類型保護只能登過這種 === 等號或者!== 不等於這種形式來定義來比較。
在js中能夠用includes判斷一個字符串或者數組裏面是否包含某個指定的東西
typeof 在ts中只能作等或者不等的操做不會把這段include的識別爲類型保護的,後面的邏輯也不會判斷出item是什麼類型的
typeof後面要比較的類型,必須這四種的一種:string、number、boolean、symbol
valueList這裏咱們修改一下
item的類型就是一個空的對象
這裏用typeof判斷object類型
因此後面的判斷不會準確的判斷
你能夠這麼寫,可是不會被識別爲類型保護
instanceof類型保護
instanceof也是js中的原生操做符,判斷一個實例是否是某個構造函數建立的實例。或者是否是使用es6語法的某個類建立的
在ts中使用instanceof一樣具備類型保護的效果
getRandomItem隨機數,若是小於0.5就建立class1的實例,若是不是 就建立class2的實例
使用instanceof類型保護,
null和undefined
是任何類型的子類型
這裏定義values默認是123會自動推斷出來是string類型
可是其實這裏的類型默認狀況下至關因而一個strng | undefined的聯合類型
values給他賦值一個undefined也是能夠的。就是上面上面定義的時候至關於string和undefined的聯合類型了。因此在ts中有嚴格模式
ts.config內有嚴格模式能夠打開,默認是關閉的。這裏打開這個選項
打開以後,把undefined賦值給values就會報錯了。values是stirng類型,這裏就不能再把undefined賦值給values了
ts會將null和undefined區別對待,這和js裏也是一致的
下面 這三種是徹底不一樣的類型
當開啓了ts的屬性strickNullChecks設置爲true了
可選參數會被自動加上undefined,成爲一個聯合類型。ts會自動作這麼一個處理
可選屬性也是會被加上undefined的 這裏不在舉例
修改了tsconfig.json之後,必定要把項目停掉,從新編譯項目npm start
類型保護和類型斷言
當咱們的參數或者屬性類型是聯合類型或者any類型這種不惟一的類型時,咱們就可能須要使用類型保護來作一些類型的判斷
定義函數,函數的返回值類型是number
精簡代碼。若是value是null這裏使用 || 會隱式轉換成false,false的話就會走後面的 空字符串的邏輯,
當value是null的時候,就會總體返回那個空字符串,而後空字符串再取length的值那麼就是0
這裏用了一個嵌套函數,裏面又套了一個函數getRes()
若是num是null就會隱式轉換爲false 就會取0.1,若是num不爲null那麼就默認返回num的值
這裏報錯了,num可能爲null,當num爲null 的時候就不能調用toFixed方法了。由於有嵌套函數,編譯器是沒法去除嵌套函數的null的
因此這裏咱們就要使用類型斷言,用歎號在不爲null的值的後面。
在num的值的後面加歎號
先取整,再toString
類型別名
就是給一種累心起一個別的名字,以後只要使用這個類型的時候,均可以用這個新的名字,做爲類型的代替。
只要你想指定類型是stirng的地方,均可以使用TypeString來指定
例如這裏,我本來是要指定str2是string類型
如今我就能夠全完用TypeString來代替
類型別名也可使用泛型,這裏用type會報錯,須要tsconfig設置interface-over-type-literal:false才能夠。要否則這裏只能用interface接口
設置爲false:interface-over-type-literal:false。本身開發項目仍是建議開啓。
使用類型別名的時候,也能夠在屬性引用本身
child屬性用了他本身自己,其實就是定義了一種樹狀的結構
一層一層的嵌套下去
只能夠在對象屬性中引用類型別名本身。不能直接使用本身。下面這種就會報錯了
類型別名只是爲其餘類型起了新的別名來引用這個類型,因此當它爲接口起別名時不能使用extends和implements
接口和類型別名有時 是起到同樣的做用的
下面先定義一個類型別名,在定義一個接口,裏面都只有屬性num屬性爲number類型,在定義_alias我能夠指定類型是Alias類型別名
同時也能夠指定_alias指定爲接口類型達到了一樣的效果
接口的實例賦值給類型別名的實例,這裏是能夠的 沒有報錯
何時用類型別名,何時使用接口?
剛纔的例子咱們使用類型別名會自動轉爲接口,tsconfig.json內這裏設置爲false了纔可使用的類型別名
當你定義的類型要用於擴展要用implements來修飾的時候用接口。當沒法經過接口,而且須要使用聯合類型或者元祖類型的時候用類型別名
自變量類型
自變量包含字符串自變量和數字自變量兩種
經過type制定Name是字符串自變量類型
制定name3類型爲Name,Name是Lison這個字符串的字符串自變量。因此我給name3賦值Lison這個字符串是沒問題的
若是給賦一個別的值
還可使用聯合類型來使用多個字符串。
Direction就是後面四個字符串的字符串自變量構成的一個聯合類型
返回傳的參數的首字母
在調用方法的時候,這裏就列出來了智能選擇這四個做爲參數
傳值哈哈就會報錯了
數字自變量
定義數字自變量Age爲18.
再定義一個接口,裏面的屬性age是自變量類型Age ,其實就是規定了智能是18
那麼在_info繼承了接口後,age的值必須是18若是不是就會報錯了
枚舉成員類型
可以作類型使用的枚舉要符合三個條件
1.不帶初始值的枚舉成員
2.成員的值爲字符串自變量。
3.值是數值自變量或者帶有一個負號的數值自變量
以上三種知足一個就能夠。那麼這個枚舉值和他的枚舉成員均可以作爲類型來使用
可辨識聯合類型
能夠把單例類型,聯合類型、類型保護、類型別名,這幾種類型合併,建立一個可辨識聯合的高級類型,也能夠成爲標籤聯合或者代數數據類型
可辨識聯合要求具備兩個要素
1.具備普通的單例類型屬性
2.一個類型別名包含了哪些類型的聯合(也就是把幾個類型封裝爲聯合類型而且起個別名)
shapes是三個接口的聯合
在寫代碼的時候,當判斷了是什麼類型,自動把接口內的屬性自動提示出來了
三個接口內都有特徵,kind而且值都不同,因此用kind來作特徵
shape別名包含了三個接口的聯合
定義函數的時候制定類型就是shape這個聯合類型。在寫switch的時候,經過編譯s.kind這個可辨識的特徵。咱們在寫下面的代碼時候,ts已經幫咱們判斷出了每一個分支的條件均可覺得(二聲)什麼
當咱們case判斷是square,他會判斷s就是Square這個接口的類型,會把你能夠訪問的屬性給你列出來。這就是一個能夠辨識的聯合
冪運算,一個星號是乘以,兩個星號就是冪運算。這就是圓的半徑的平方。冪運算我聽着視頻說的不是很清楚,多是ES7的語法
一共三種類型,這裏若是漏了 但願編譯器給予提示
就要用到下一個知識點。什麼什麼檢查。
兩種檢查方式,
先肯定這個屬性是不是true,打開的
指定返回類型,若是遺漏了就會報錯
若是沒有開tsconfig.json內的strictNullCheck。這裏的返回值類型能夠設置爲undefined.編譯器會自動認爲這裏返回值類型是個聯合類型number或者undefined
既然開了strictNullCheck已經設置爲true了,就是打開了。這裏的分支沒有任何一條執行,就會返回undefined。undefined和number是不能賦值的。因此這裏我就知道少了一個分支。
這種方法比較簡單,可是對舊的代碼支持很差。由於之前沒有strictNullCheck這個選項
第二種方法:
當一個函數返回錯誤,坐着不可能有返回值類型的時候,返回值的類型爲never,因此咱們能夠給switch添加一個default
先把這個註釋掉
關掉後,這裏就不報錯了
須要定義一個額外的函數,接收參數是never類型,返回值類型也是never。而後在switch裏面加一個default的分支。
若是缺乏了一個項,就會走定義的函數assertNevert函數,就會提示報錯 。
不只在編譯器提示咱們錯誤運行的時候也會報錯。