<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
隨著越來越多的前端專案採用 typescript 來開發,越來越多前端開發者會接觸、使用這門語言。它是前端專案工程化的一個重要幫手,結合 vscode 編輯器,給予了前端開發者更嚴謹、高效的編碼體驗。但同時,嚴格的型別檢查也會使部分開發者的編碼效率有所降低,將時間花費在解決型別衝突、型別不匹配上,從而導致望而卻步,遲遲不敢上手。
本文描述了幾種繞過 typescript 型別檢查的方法,幫助ts開發者在遇上第三方庫型別宣告有誤、上線時間緊張卻還被ts型別耽擱開發進度、以及其他奇奇怪怪ts型別宣告的場景時,能夠快速擺脫ts型別檢測,保障專案儘快上線。
注意,本文所提到的方法,只能作為一種最後不得已的hack手段,其目的是為了儘快完成需求而非程式碼取巧,讀者不應該將其當成一種常用的寫法並在專案內任意使用!
假設存在一個第三方庫,允許開發者通過 json 定義一個表單,其 typescript 型別定義如下:
interface FormItem{ /** 表單型別 */ type:string /** 顯示文字 */ label:string } interface FormSelectItem extends FormItem{ /** 將表單型別指定為'select' */ type:'select' /** 新增一個options屬性,型別為陣列,此型別定義存在錯誤,沒有定義options陣列裡面的內容 */ options:[] } type FormRule = (FormSelectItem|FormItem)[]
程式碼裡,FormSelectItem.options
期望的是一個有內容的陣列,但因為第三方庫給定的型別檔案編寫錯誤,沒有給出陣列內部項的結構,只留下[]
空陣列型別定義,導致開發者給FormSelectItem.options
賦予一個有內容的陣列都會導致 typescript 報錯。
//@ts-ignore
會讓typescript編譯器跳過註釋下一行程式碼,不對其進行型別檢查。通過不檢查型別的方式,繞過型別檢查
//@ts-ignore window.aaaa = "使用範例(ts裡不允許通過此行程式碼往全域性物件掛載屬性)"
加上//@ts-ignore
在options
屬性之上,編譯器跳過了options
屬性的檢查,因此報錯消失。使用起來十分簡單快捷,但是加了註釋忽略之後,開發者為options
賦予任何值都是合法的,如非陣列的物件、null、undefined等容易引起程式出錯的型別。同時加了//@ts-ignore
之後,編輯器無法再對此行進行程式碼提示和自動補全。
型別斷言是typescript中一種將一個型別指定為另一個型別的語法。通過指定任意型別為目標型別的方式,達到編譯器不報錯的效果。
(window as unknown as {aaa:string}).aaa = "使用範例(ts裡不允許通過此行程式碼往全域性物件掛載屬性)"
上圖使用了斷言語法,且用到兩種斷言方式:
{label:string,value:string}[]
斷言為[]
,使得能夠與options
的型別匹配上。在屬性賦值中只能使用此種斷言寫法。[]
斷言為{label:string,value:string}[]
,使得select.options
能夠按照開發者的資料型別進行工作。並且通過此種方式,對select.options
進行操作時,編輯器還會根據開發者的斷言型別進行語法提示。相比註釋忽略,型別斷言原本就是typescript語法的一部分,本身就會接受型別檢查,因此後續的程式碼補全提示功能是完整的。但同時開發者主觀上應當明白型別斷言的作用,避免將不正確的資料型別傳入導致程式碼出錯。
泛型是typescript最強大的功能,它提供給了開發者們對型別“程式設計”的能力。通過定義泛型輔助函數,在型別斷言的基礎上,利用函數返回泛型的手段,巧妙地將型別匹配上,從而達到縮小程式碼量且編譯器不報錯的效果。
function _any<T>(obj:any):T{ return obj as unknown as T } _any<{aaa:string}>(window).aaa='使用範例(ts裡不允許通過此行程式碼往全域性物件掛載屬性)'
實際上,輔助函數也只是將引數當作是返回值而已,只不過利用泛型可以指定為任意型別。
甚至可以設定兩個泛型:一個是目標泛型,也就是函數要返回的資料型別,一個是引數泛型,也就是傳入的資料型別。當顯式地賦予泛型P一個型別時,typescript可以為引數提供型別檢查和語法補全。
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:'' })
相比型別斷言,使用泛型轉換輔助函數的做法最大的作用,是簡化了as unknow as xxx
的寫法,本質上還是一樣的。開發者同樣需要明白轉型別的作用,避免使用錯誤的型別導致程式碼錯誤。
遇上型別對不上,專案又急著上線,缺乏足夠的時間跟typescript編譯器慢慢折騰的情況下,可以酌情使用註釋忽略、型別斷言、泛型轉換的方法來強行指定型別。
其中註釋忽略是利用編譯器跳過的方式,停止型別檢查,帶來的後果就是該行其他資料無法獲得型別校驗;
型別斷言、泛型轉換都通過斷言的語法,強行指定型別,使型別對應上,進而通過編譯;
而泛型轉換是利用輔助函數的寫法,來減少斷言程式碼的編寫。
但這三種方式都存在風險,開發者都需要明白賦予的資料型別的含義,避免資料錯誤導致程式碼出錯。
以上就是詳解Anyscript開發指南繞過typescript型別檢查的詳細內容,更多關於Anyscript繞過typescript型別檢查的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45