詳細(xì)聊聊TypeScript中unknown與any的區(qū)別
前言
我們知道 any 類型的變量可以被賦給任何值。
let myVar: any = 0; myVar = '1'; myVar = false;
TypeScript 指南并不鼓勵(lì)使用 any,因?yàn)槭褂盟蜁?huì)丟掉類型限制--而需要類型限制也是我們選擇 TypeScript 的一個(gè)原因,所以就是有點(diǎn)背道而馳。
TypeScript(3.0 及以上版本)還提供了一種類似于 any 的特殊類型 unknown。 我們也可以為 unknown 類型變量分配任何值:
let myVar: unknown = 0; myVar = '1'; myVar = false;
那現(xiàn)在就有一個(gè)問題了, any 和 unknown 有啥區(qū)別?
1. unknown vs any
為了更好地理解 unknown 和 any 之間的區(qū)別,我們先從編寫一個(gè)想要調(diào)用其唯一參數(shù)的函數(shù)開始。
我們將 invokeAnything() 的唯一參數(shù)設(shè)置為 any 類型
function invokeAnything(callback: any) {
callback();
}
invokeAnything(1); // throws "TypeError: callback is not a function"
因?yàn)?callback 參數(shù)是任何類型的,所以語句 callback() 不會(huì)觸發(fā)類型錯(cuò)誤。我們可以用any 類型的變量做任何事情。
但是運(yùn)行會(huì)拋出一個(gè)運(yùn)行時(shí)錯(cuò)誤:TypeError: callback is not a function。1 是一個(gè)數(shù)字,不能作為函數(shù)調(diào)用,TypeScript并沒有保護(hù)代碼避免這個(gè)錯(cuò)誤
那既允許 invokeAnything() 函數(shù)接受任何類型的參數(shù),又要強(qiáng)制對(duì)該參數(shù)進(jìn)行類型檢查防止上面這種報(bào)錯(cuò),要怎么做呢?
有請(qǐng) unknown 大哥來控場(chǎng)。
與 any 一樣,unknown 變量接受任何值。但是當(dāng)嘗試使用 unknown 變量時(shí),TypeScript 會(huì)強(qiáng)制執(zhí)行類型檢查。這不就是我們想要的嘛。
function invokeAnything(callback: unknown) {
callback();
// Object is of type 'unknown'
}
invokeAnything(1);
因?yàn)?callback 參數(shù)的類型是 unknown,所以語句 callback() 有一個(gè)類型錯(cuò)誤 :Object is of type 'unknown'。 與 any 相反,TypeScript會(huì)保護(hù)我們不調(diào)用可能不是函數(shù)的東西。
在使用一個(gè) unknown 類型的變量之前,你需要進(jìn)行類型檢查。在這個(gè)例子中,我們只需要檢查callback 是否是一個(gè)函數(shù)類型。
function invokeAnything(callback: unknown) {
if (typeof callback === 'function') {
callback();
}
}
invokeAnything(1);
2. unknown 和 any 的心智模式
說實(shí)話,當(dāng)我學(xué)習(xí)的時(shí)候,我很難理解 unknown 。它與 any 有什么不同,因?yàn)檫@兩種類型都接受任何值
下面是幫助我理解兩者區(qū)別的規(guī)則:
- 可以將任何東西賦給 unknown 類型,但在進(jìn)行類型檢查或類型斷言之前,不能對(duì) unknown 進(jìn)行操作
- 可以把任何東西分配給any類型,也可以對(duì)any類型進(jìn)行任何操作
上面的例子正好說明了 unknown 和 `any 之間的相似和不同。
unknown 示例:
function invokeAnything(callback: unknown) {
// 可以將任何東西賦給 `unknown` 類型,
// 但在進(jìn)行類型檢查或類型斷言之前,不能對(duì) `unknown` 進(jìn)行操作
if (typeof callback === 'function') {
callback();
}
}
invokeAnything(1); // You can assign anything to `unknown` type
類型檢查 typeof callback === 'function',檢查 callback 是否為函數(shù),如果是,則可以調(diào)用。
any 示例:
function invokeAnything(callback: any) {
// 可以對(duì) `any` 類型執(zhí)行任何操作
callback();
}
invokeAnything(1); // 可以把任何東西分配給`any`類型
如果 callback是 any, TypeScript 就不會(huì)強(qiáng)制 callback() 語句進(jìn)行任何類型檢查。
3.總結(jié)
unknown和 any 是2個(gè)特殊的類型,可以容納任何值。
推薦使用 unknown 而不是 any,因?yàn)樗峁┝烁踩念愋?-如果想對(duì) unknown 進(jìn)行操作,必須使用類型斷言或縮小到一個(gè)特定的類型。
~~ 完,我是小智,女票在教培行業(yè)工作,最近發(fā)的工資有點(diǎn)低,我準(zhǔn)備多多下海工作,賺更多的錢了。
編輯中可能存在的bug沒法實(shí)時(shí)知道,事后為了解決這些bug,花了大量的時(shí)間進(jìn)行l(wèi)og 調(diào)試,這邊順便給大家推薦一個(gè)好用的BUG監(jiān)控工具 Fundebug。
原文:dmitripvlutin.com/typescript-…
總結(jié)
到此這篇關(guān)于TypeScript中unknown與any區(qū)別的文章就介紹到這了,更多相關(guān)TypeScript unknown與any區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序獲取驗(yàn)證碼60秒倒計(jì)時(shí)功能
這篇文章主要介紹了微信小程序獲取驗(yàn)證碼60秒倒計(jì)時(shí)模板,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-04-04
微信小程序?qū)崿F(xiàn)上拉加載功能示例【加載更多數(shù)據(jù)/觸底加載/點(diǎn)擊加載更多數(shù)據(jù)】
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)上拉加載功能,結(jié)合實(shí)例形式分析了微信小程序加載更多數(shù)據(jù)、觸底加載或點(diǎn)擊加載更多數(shù)據(jù)的相關(guān)實(shí)現(xiàn)技巧與操作注意事項(xiàng),需要的朋友可以參考下2020-05-05
javascript事件的綁定基礎(chǔ)實(shí)例講解(34)
這篇文章主要為大家詳細(xì)介紹了javascript事件的綁定基礎(chǔ)實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02
ionic2自定義cordova插件開發(fā)以及使用(Android)
這篇文章主要為大家詳細(xì)介紹了ionic2自定義cordova插件開發(fā)以及使用,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
使用KrpanoToolJS在瀏覽器切圖的實(shí)例詳解
這篇文章主要介紹了使用KrpanoToolJS在瀏覽器切圖的實(shí)例詳解,大概是需要在瀏覽器中將全景圖轉(zhuǎn)為立方體圖、多層級(jí)瓦片圖,通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10
簡(jiǎn)單了解微信小程序的目錄結(jié)構(gòu)
這篇文章主要介紹了簡(jiǎn)單了解小程序的目錄結(jié)構(gòu),在開發(fā)小程序之前,我們首先需要對(duì)其目錄結(jié)構(gòu)進(jìn)行了解,以便于提升開發(fā)效率,需要的朋友可以參考下2019-07-07
微信小程序修改swiper默認(rèn)指示器樣式的實(shí)例代碼
這篇文章主要介紹了微信小程序修改swiper默認(rèn)指示器樣式的實(shí)例代碼,代碼塊是從微信開發(fā)文檔中心復(fù)制的代碼塊,在此基礎(chǔ)上修改官方swiper樣式,需要的朋友可以參考下2018-07-07
js document.getElementsByClassName的使用介紹與自定義函數(shù)
今天在增加一個(gè)功能的時(shí)候需要用到getElementsByClassName(),getElementsByClassName但是HTML5 新增的DOM API。IE8以下不支持,那么就需要下面的方法解決了2016-11-11

