tft每日頭條

 > 圖文

 > ts語言可以做什麼

ts語言可以做什麼

圖文 更新时间:2024-12-26 15:22:21

ts語言可以做什麼(TS短文3分鐘細品下unknown和never類型)1

字數:1712字 閱讀: 3 分鐘

大家好,今天和大家聊下讓我曾經迷惑的兩個TS類型:unknown 和 never,不知道大家有沒有對其用法有所迷惑呢,好記性比不過爛筆頭,為了讓我不再迷惑,還是通過文字的形式整理下加深下印象比較靠譜,希望今天的分享能給大家解惑。

一、unknown 類型

unknown 類型是 TS3 新增的類型,這個類型與 any 類型類似,可以設置任何的類型值,随後可以更改類型。因此,我們可以将變量先設置為字符串類型,然後再将其設置為數字類型,如果事先不檢查類型,使用any類型,調用了不存在的方法,編譯時不會報錯,代碼運行時才會發現錯誤。但是使用unknown 類型不一樣,如果不進行類型判斷,執行相關操作編譯器就會報錯。文字說了這麼多,還是上代碼,更容易理解些。

1、關于 Any 的問題

首先我們創建一個 any.ts 的文件,代碼如下:

letval:any=22; val="stringvalue"; val=newArray(); val.push(33); console.log(val);

運行編譯後的代碼,并不會報錯,也是按照我們的預期輸出: [33]

由于是 any 類型,我們可以随意更改類型,當變成數組類型時,我們調用push方法進行内容操作,看似沒啥問題,如果我們開發人員,如果由于疏忽,打錯了一個不存在的方法,ts代碼能正常編譯嗎?

letval:any=22; val="stringvalue"; val=newArray(); val.doesnotexist(33); console.log(val);

當運行 tsc any 命令後,你會發現編譯器能順利編譯,當我們運行 node any,編譯後的代碼能正常執行嗎?答案是顯而易見的,會報異常,你會在控制台發現以下錯誤:

val.doesnotexist(33); ^ TypeError:val.doesnotexistisnotafunction

上述的錯誤,大家可能不會犯,但是項目大時,參與的人多時,就很難避免這樣類似的問題,因此unknown 類型出現了。

2、一段 unknown 類型的代碼

接下來我們來看看它是怎麼解決類似的問題,我們還是從一段簡單的代碼開始,如下段代碼所示:

letval:unknown=22; val="stringvalue"; val=newArray(); val.push(33); console.log(val);

當你編譯此代碼時,你會立馬收到如下報錯:

Property'push'doesnotexistontype'unknown'.

是不是很奇怪,雖然我們将其類型更改為數組類型,但是編譯器不認識,它認為unknown類型,這個類型沒有push方法,當然會報錯,除非先判斷類型,如果是相關類型且正确執行相關方法,編譯器則會順利通過,如下段代碼所示

letval:unknown=22; val="stringvalue"; val=newArray(); if(valinstanceofArray){ val.push(33); } console.log(val);

雖然有些麻煩,但是相比 any 類型說,更加安全,在代碼編譯期間,就能幫我們發現由于類型造成的問題,因此在大多的場景,建議使用 unknown 類型替代 any。

二、never 類型

這個類型看起來有些奇怪,乍一看,看起來和void相似,但是其完全不一樣。從字面意思上來說,表示一個從來不會有返回值的函數(例:while(true) {}),一個總是會抛出錯誤的函數(function foo() { throw new Error('Not Implemented') })。那麼問題來了,它和 void 類型啥區别,void 表示沒有任何類型,函數沒有返回值時(可以返回,但是沒值),我們可以設置為void 類型;never這不一樣,一個函數根本就沒返回(或者總是出錯,永遠不會有返回值)。看文字有些費勁,我們還是來看一段簡單的代碼來理解下吧,如下所示:

functionalwaysThrows():never{ throw"thiswillalwaysthrow"; return-1; }

當我們編譯上述代碼時,編譯器就會報錯,如下所示:

Type'number'isnotassignabletotype'never'.

編譯器已經很明确地告訴了我們 never 類型不應該返回任何值(或抛異常)。那麼問題來了,這個類型有啥用呢?我們還是舉個例子來理解下吧,比如你有個 enum 枚舉類型,代碼如下所示:

enumTestNeverEnum{ FIRST, SECOND }

在 switch 當中判斷 type,TS 是可以收窄類型的 (discriminated union):

enumTestNeverEnum{ FIRST, SECOND } functiongetEnumValue(value:TestNeverEnum):string{ switch(value){ //這裡value被收窄為TestNeverEnum.FIRST caseTestNeverEnum.FIRST:return"Firstcase"; //這裡value被收窄為TestNeverEnum.SECOND caseTestNeverEnum.SECOND:return"Secondcase"; //returnValue是never類型 default:constreturnValue:never=value; } }

注意在 default 裡面我們把被收窄為 never 的 returnValue 賦值給一個顯式聲明為 never 的變量。如果一切邏輯正确,那麼這裡應該能夠編譯通過。但是假如有一天你的同事增加了TestNeverEnum 枚舉類型:

enumTestNeverEnum{ FIRST, SECOND, THIRD }

然而他忘記了在 getEnumValue 裡面加上針對 THIRD 的處理邏輯,這個時候在 default branch 裡面 returnValue 會被收窄為 TestNeverEnum.THIRD,導緻無法賦值給 never(因為有值返回),産生一個編譯錯誤。編譯器會産生如下的錯誤:

Type'TestNeverEnum'isnotassignabletotype'never'.

所以通過這個辦法,你可以确保 getEnumValue 方法裡總是窮盡 (TestNeverEnum) 了所有 All 的可能類型,目的就是寫出類型絕對安全的代碼。

三、結束語

今天的内容就到這裡,這兩個類型你弄明白了嗎?雖然内容不多,但是需要細品 ,才能理解其應用場景和用好它們,感謝的閱讀。

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关圖文资讯推荐

热门圖文资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved