詳解Anyscript開發(fā)指南繞過typescript類型檢查
前言
隨著越來越多的前端項(xiàng)目采用 typescript 來開發(fā),越來越多前端開發(fā)者會接觸、使用這門語言。它是前端項(xiàng)目工程化的一個(gè)重要幫手,結(jié)合 vscode 編輯器,給予了前端開發(fā)者更嚴(yán)謹(jǐn)、高效的編碼體驗(yàn)。但同時(shí),嚴(yán)格的類型檢查也會使部分開發(fā)者的編碼效率有所降低,將時(shí)間花費(fèi)在解決類型沖突、類型不匹配上,從而導(dǎo)致望而卻步,遲遲不敢上手。
本文描述了幾種繞過 typescript 類型檢查的方法,幫助ts開發(fā)者在遇上第三方庫類型聲明有誤、上線時(shí)間緊張卻還被ts類型耽擱開發(fā)進(jìn)度、以及其他奇奇怪怪ts類型聲明的場景時(shí),能夠快速擺脫ts類型檢測,保障項(xiàng)目盡快上線。
注意,本文所提到的方法,只能作為一種最后不得已的hack手段,其目的是為了盡快完成需求而非代碼取巧,讀者不應(yīng)該將其當(dāng)成一種常用的寫法并在項(xiàng)目內(nèi)任意使用!
場景設(shè)定
假設(shè)存在一個(gè)第三方庫,允許開發(fā)者通過 json 定義一個(gè)表單,其 typescript 類型定義如下:
interface FormItem{ /** 表單類型 */ type:string /** 顯示文本 */ label:string } interface FormSelectItem extends FormItem{ /** 將表單類型指定為'select' */ type:'select' /** 新增一個(gè)options屬性,類型為數(shù)組,此類型定義存在錯(cuò)誤,沒有定義options數(shù)組里面的內(nèi)容 */ options:[] } type FormRule = (FormSelectItem|FormItem)[]
代碼里,FormSelectItem.options
期望的是一個(gè)有內(nèi)容的數(shù)組,但因?yàn)榈谌綆旖o定的類型文件編寫錯(cuò)誤,沒有給出數(shù)組內(nèi)部項(xiàng)的結(jié)構(gòu),只留下[]
空數(shù)組類型定義,導(dǎo)致開發(fā)者給FormSelectItem.options
賦予一個(gè)有內(nèi)容的數(shù)組都會導(dǎo)致 typescript 報(bào)錯(cuò)。
解決方法
注釋忽略
//@ts-ignore
會讓typescript編譯器跳過注釋下一行代碼,不對其進(jìn)行類型檢查。通過不檢查類型的方式,繞過類型檢查
//@ts-ignore window.aaaa = "使用示例(ts里不允許通過此行代碼往全局對象掛載屬性)"
場景用例
加上//@ts-ignore
在options
屬性之上,編譯器跳過了options
屬性的檢查,因此報(bào)錯(cuò)消失。使用起來十分簡單快捷,但是加了注釋忽略之后,開發(fā)者為options
賦予任何值都是合法的,如非數(shù)組的對象、null、undefined等容易引起程序出錯(cuò)的類型。同時(shí)加了//@ts-ignore
之后,編輯器無法再對此行進(jìn)行代碼提示和自動(dòng)補(bǔ)全。
類型斷言
類型斷言是typescript中一種將一個(gè)類型指定為另一個(gè)類型的語法。通過指定任意類型為目標(biāo)類型的方式,達(dá)到編譯器不報(bào)錯(cuò)的效果。
(window as unknown as {aaa:string}).aaa = "使用示例(ts里不允許通過此行代碼往全局對象掛載屬性)"
場景用例
上圖使用了斷言語法,且用到兩種斷言方式:
- 第一種寫法是給賦值數(shù)據(jù)下斷言,將數(shù)據(jù)類型強(qiáng)制斷言為定義類型,即在上圖中,將
{label:string,value:string}[]
斷言為[]
,使得能夠與options
的類型匹配上。在屬性賦值中只能使用此種斷言寫法。 - 第二種寫法是反過來,通過將定義類型強(qiáng)制斷言為數(shù)據(jù)類型,即在上圖中,將
[]
斷言為{label:string,value:string}[]
,使得select.options
能夠按照開發(fā)者的數(shù)據(jù)類型進(jìn)行工作。并且通過此種方式,對select.options
進(jìn)行操作時(shí),編輯器還會根據(jù)開發(fā)者的斷言類型進(jìn)行語法提示。
相比注釋忽略,類型斷言原本就是typescript語法的一部分,本身就會接受類型檢查,因此后續(xù)的代碼補(bǔ)全提示功能是完整的。但同時(shí)開發(fā)者主觀上應(yīng)當(dāng)明白類型斷言的作用,避免將不正確的數(shù)據(jù)類型傳入導(dǎo)致代碼出錯(cuò)。
泛型轉(zhuǎn)換
泛型是typescript最強(qiáng)大的功能,它提供給了開發(fā)者們對類型“編程”的能力。通過定義泛型輔助函數(shù),在類型斷言的基礎(chǔ)上,利用函數(shù)返回泛型的手段,巧妙地將類型匹配上,從而達(dá)到縮小代碼量且編譯器不報(bào)錯(cuò)的效果。
function _any<T>(obj:any):T{ return obj as unknown as T } _any<{aaa:string}>(window).aaa='使用示例(ts里不允許通過此行代碼往全局對象掛載屬性)'
實(shí)際上,輔助函數(shù)也只是將參數(shù)當(dāng)作是返回值而已,只不過利用泛型可以指定為任意類型。
甚至可以設(shè)置兩個(gè)泛型:一個(gè)是目標(biāo)泛型,也就是函數(shù)要返回的數(shù)據(jù)類型,一個(gè)是參數(shù)泛型,也就是傳入的數(shù)據(jù)類型。當(dāng)顯式地賦予泛型P一個(gè)類型時(shí),typescript可以為參數(shù)提供類型檢查和語法補(bǔ)全。
function _any<T,P=any>(obj:P):T{ return obj as unknown as T } const select:FormSelectItem = { type:'select', options:_any<[],{label:string,value:string}[]>([{ label:'', value:'' }]) } _any<{label:string,value:string}[]>(select.options).push({ label:'', value:'' })
場景用例
相比類型斷言,使用泛型轉(zhuǎn)換輔助函數(shù)的做法最大的作用,是簡化了as unknow as xxx
的寫法,本質(zhì)上還是一樣的。開發(fā)者同樣需要明白轉(zhuǎn)類型的作用,避免使用錯(cuò)誤的類型導(dǎo)致代碼錯(cuò)誤。
總結(jié)
遇上類型對不上,項(xiàng)目又急著上線,缺乏足夠的時(shí)間跟typescript編譯器慢慢折騰的情況下,可以酌情使用注釋忽略、類型斷言、泛型轉(zhuǎn)換的方法來強(qiáng)行指定類型。
其中注釋忽略是利用編譯器跳過的方式,停止類型檢查,帶來的后果就是該行其他數(shù)據(jù)無法獲得類型校驗(yàn);
類型斷言、泛型轉(zhuǎn)換都通過斷言的語法,強(qiáng)行指定類型,使類型對應(yīng)上,進(jìn)而通過編譯;
而泛型轉(zhuǎn)換是利用輔助函數(shù)的寫法,來減少斷言代碼的編寫。
但這三種方式都存在風(fēng)險(xiǎn),開發(fā)者都需要明白賦予的數(shù)據(jù)類型的含義,避免數(shù)據(jù)錯(cuò)誤導(dǎo)致代碼出錯(cuò)。
以上就是詳解Anyscript開發(fā)指南繞過typescript類型檢查的詳細(xì)內(nèi)容,更多關(guān)于Anyscript繞過typescript類型檢查的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
sessionStorage多Tab標(biāo)簽頁數(shù)據(jù)共享問題分析
這篇文章主要為大家介紹了sessionStorage多Tab標(biāo)簽頁數(shù)據(jù)共享問題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07微信小程序 scroll-view隱藏滾動(dòng)條詳解
這篇文章主要介紹了微信小程序 scroll-view隱藏滾動(dòng)條和跳轉(zhuǎn)頁面的相關(guān)資料,需要的朋友可以參考下2017-01-01關(guān)于JavaScript防抖與節(jié)流的區(qū)別與實(shí)現(xiàn)
這篇文章主要介紹關(guān)于JavaScript防抖與節(jié)流的區(qū)別與實(shí)現(xiàn),防抖就是用戶多次觸發(fā)事件,在用戶一直觸發(fā)事件中,事件不會執(zhí)行,只有在用戶停止觸發(fā)事件一段時(shí)間之后再執(zhí)行這個(gè)事件一次,二節(jié)流是用戶多次觸發(fā)事件,具體詳情一i起來學(xué)習(xí)下面文章內(nèi)容吧2021-10-10JavaScript節(jié)點(diǎn)的增刪改查深入學(xué)習(xí)
這篇文章主要為大家介紹了JavaScript節(jié)點(diǎn)的增刪改查深入學(xué)習(xí)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01