淺談TypeScript3.7中值得注意的3個(gè)新特性
前言
距typescript 3.7正式發(fā)布已經(jīng)有一段時(shí)間了,這段時(shí)間正在對(duì)手上的項(xiàng)目進(jìn)行typescript的遷移工作,所以會(huì)特別留意每一次的release。
對(duì)于3.7中包含的新特性,其實(shí)相比較之前幾次release來(lái)說(shuō),算是一個(gè)比較小的發(fā)布版本,但是其中包含的幾個(gè)特性對(duì)代碼質(zhì)量本身,會(huì)帶來(lái)顯著地提升。
Optional Chaining
首先第一個(gè)特性是對(duì)于optional chaining操作符的支持,翻譯過(guò)來(lái)應(yīng)該可以叫做可選鏈操作符,當(dāng)然我還是覺(jué)得這樣翻譯有點(diǎn)怪怪的,暫且就直接用英文好了。
這個(gè)特性首先是es2019中包含的一個(gè)新特性,對(duì)于特性本身,有興趣的可以參考這里。
由于typescript是JavaScript的超集,所以預(yù)先實(shí)現(xiàn)這個(gè)特性也是在預(yù)料之內(nèi)的事情,大概使用方式是這樣的:
a?.b();
等價(jià)于:
if(a) a.b(); // 或者 a && a.b()
如果是多層嵌套,比如b也是一個(gè)對(duì)象,要繼續(xù)調(diào)用c(),那么可以這樣:
a?.b?.c()
但其實(shí)就算這樣寫(xiě)的話,它也不是安全的,因?yàn)閎()中的b也有可能是空值,直接調(diào)用的話,也會(huì)拋出異常。為了絕對(duì)的安全,可以這樣寫(xiě):
a?.b?.();
值得注意的是,這里一定要對(duì)于可選的含義有一個(gè)正確的理解,可選的意思是,它在類(lèi)型的聲明中,通過(guò)?來(lái)修飾,代表一個(gè)類(lèi)型包含某個(gè)可為空值的屬性。言外之意的意思就是,?.不會(huì)對(duì)那些不符合類(lèi)型聲明本身的屬性調(diào)用,比如:
interface A {} const a: A = {}; a?.b?.(); // Property 'b' does not exist on type 'A'
除非A接口的聲明改為:
interface A { b?: any }
這個(gè)特性在項(xiàng)目的實(shí)踐意義是很大的,我們可以寫(xiě)更少的if斷言語(yǔ)句或者&&操作符,但是卻達(dá)到了相同的效果。
Nullish Coalescing
中文翻譯過(guò)來(lái)會(huì)叫做雙問(wèn)號(hào)操作符,這個(gè)其實(shí)挺形象的,因?yàn)樗恼Z(yǔ)法確實(shí)就是??。
這個(gè)操作符的功能,往簡(jiǎn)單說(shuō),就是為一個(gè)空值,指定一個(gè)默認(rèn)值,類(lèi)似下面的代碼:
let a = b || 'foo'
當(dāng)b為空值時(shí),由于||操作符的特性,a的值會(huì)被賦予foo。如果使用??操作符進(jìn)行改寫(xiě),如下:
let a = b ?? 'foo'
表面上看,似乎兩者沒(méi)什么區(qū)別,但其實(shí)這里隱含了一個(gè)問(wèn)題,就是||對(duì)于空值的概念,并不僅僅指null和undefined,類(lèi)似false、0等一系列邏輯上為false的值都會(huì)算作空值,這顯然是有問(wèn)題的,比如:
const b = 0 let a = b || 'foo' // a 為 'foo'
這個(gè)示例中,我們期望a只有在b為真正意義上的空值(null或者undefined)時(shí),才被賦予默認(rèn)值,a應(yīng)當(dāng)?shù)扔?,而實(shí)際運(yùn)行結(jié)果確實(shí)foo,因?yàn)閎=0,在||操作符的運(yùn)行過(guò)程中,它會(huì)被解釋為false。我曾在實(shí)際項(xiàng)目中,編寫(xiě)過(guò)一個(gè)驗(yàn)證碼組件,很不幸,踩上了這個(gè)坑,當(dāng)時(shí)為了debug這個(gè)問(wèn)題,花了很長(zhǎng)時(shí)間。
但使用??操作符,就不會(huì)存在這個(gè)問(wèn)題。
Uncalled Function Checks
我相信很多人都曾經(jīng)遇過(guò)類(lèi)似的問(wèn)題,因?yàn)槿狈τ行У拿?guī)范,斷言屬性和斷言方法會(huì)在實(shí)際項(xiàng)目中被混用,比如:
class A { isFoo(): boolean { return false; } } function test(a: A) { if (a.isFoo) { ... } }
這里如果我們的本意是要通過(guò)調(diào)用a.isFoo來(lái)獲取一個(gè)斷言值,我們明顯犯了一個(gè)錯(cuò)誤,我們應(yīng)當(dāng)使用if (a.isFoo()),而不是直接if (a.isFoo),因?yàn)楹笳唠m然在語(yǔ)法層面沒(méi)有錯(cuò)誤,但是在邏輯含義,它將被斷言為true。但在3.7發(fā)布之后,typescript會(huì)嘗試幫助我們發(fā)現(xiàn)這個(gè)問(wèn)題。
雖然如此,但我仍然建議大家針對(duì)斷言方法和斷言屬性制定統(tǒng)一的命名規(guī)范,比如isXXX代表屬性,而assertXXX代表方法。
其他
其他的一些變更,均是易用性上的一些改變,比如:
- Flatter Error Reporting:會(huì)將一大段的類(lèi)型重復(fù)的錯(cuò)誤日志,盡可能地壓縮為單條、更準(zhǔn)確、更精簡(jiǎn)的錯(cuò)誤日志
- 文件級(jí)別的@ts-nocheck:之前版本中該注解僅支持行內(nèi)級(jí)別
- 遞歸類(lèi)型聲明:能夠在類(lèi)型聲明中,使用遞歸語(yǔ)法來(lái)聲明更復(fù)雜的類(lèi)型,比如json類(lèi)型
- 對(duì)js文件提供declaration支持,以減小從js項(xiàng)目遷移的遷移成本
以上就是淺談TypeScript3.7中值得注意的3個(gè)新特性的詳細(xì)內(nèi)容,更多關(guān)于TypeScript3.7新特性的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
比較詳細(xì)的javascript對(duì)象的property和prototype是什么一種關(guān)系
比較詳細(xì)的javascript對(duì)象的property和prototype是什么一種關(guān)系...2007-08-08Vue項(xiàng)目vscode 安裝eslint插件的方法(代碼自動(dòng)修復(fù))
這篇文章主要介紹了Vue項(xiàng)目vscode 安裝eslint插件的方法 代碼自動(dòng)修復(fù),需要的朋友可以參考下2020-04-04window.ActiveXObject使用說(shuō)明
判斷瀏覽器是否支持ActiveX控件,如果瀏覽器支持ActiveX控件可以利用2010-11-11前臺(tái)js對(duì)象在后臺(tái)轉(zhuǎn)化java對(duì)象的問(wèn)題探討
在開(kāi)發(fā)項(xiàng)目中多次遇到前臺(tái)js對(duì)象在后臺(tái)轉(zhuǎn)化java對(duì)象的問(wèn)題,下面就為大家介紹下前臺(tái)js對(duì)象轉(zhuǎn)后臺(tái)java對(duì)象,感興趣的朋友可以了解下2013-12-12JS實(shí)現(xiàn)超簡(jiǎn)潔網(wǎng)頁(yè)title標(biāo)題跑動(dòng)閃爍提示效果代碼
這篇文章主要介紹了JS實(shí)現(xiàn)超簡(jiǎn)潔網(wǎng)頁(yè)title標(biāo)題跑動(dòng)閃爍提示效果代碼,涉及JavaScript結(jié)合定時(shí)函數(shù)動(dòng)態(tài)操作頁(yè)面元素屬性的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10textarea焦點(diǎn)的用法實(shí)現(xiàn)獲取焦點(diǎn)清空失去焦點(diǎn)提示效果
這篇文章主要介紹了textarea焦點(diǎn)的用法實(shí)現(xiàn)獲取焦點(diǎn)清空失去焦點(diǎn)提示效果,需要的朋友可以參考下2014-05-05element-plus 官方表格排序問(wèn)題小結(jié)
在使用Element Plus官方API時(shí),表格默認(rèn)排序可能會(huì)遇到問(wèn)題,一個(gè)列表可能被多次排序影響數(shù)據(jù)展示,解決方法是修改useSortTable.js文件,這樣可以確保表格按預(yù)期正確排序,更多詳情可查閱相關(guān)的技術(shù)文檔或資源2024-10-10如何設(shè)置iframe高度自適應(yīng)在跨域情況下的可用方法
iframe的高度需要根據(jù)子頁(yè)面的實(shí)際高度來(lái)進(jìn)行調(diào)整,但是如果子頁(yè)面不在同一域中怎么辦?這時(shí)候腳本沒(méi)有辦法獲取到子頁(yè)面的高度,存在JavaScript跨域的問(wèn)題2013-09-09微信小程序wx.getUserInfo授權(quán)獲取用戶信息(頭像、昵稱(chēng))的實(shí)現(xiàn)
這篇文章主要介紹了微信小程序wx.getUserInfo授權(quán)獲取用戶信息(頭像、昵稱(chēng))的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08JS使用oumousemove和oumouseout動(dòng)態(tài)改變圖片顯示的方法
這篇文章主要介紹了JS使用oumousemove和oumouseout動(dòng)態(tài)改變圖片顯示的方法,涉及javascript鼠標(biāo)事件及圖片操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03