近日,有開發者在知乎上提出了一個問題:“TypeScript 不適合在 vue 業務開發中使用嗎?”,Vue的作者尤雨溪針對這一問題發表了自己的看法,也解釋了Vue 3.0選用TypeScript的原因,全文如下。愛掏網 - it200.com
注:本文已獲得尤雨溪本人授權轉載。愛掏網 - it200.com
必須要承認的是,2.x 的 TS 支持顯然跟 React 和 Angular 是有差距的,這也是為什么 3.0 要加強這一塊。愛掏網 - it200.com
關于目前 2.x 跟 TS 的整合,通常需要基于 vue-class-component 來用基于 class 的組件書寫方式。愛掏網 - it200.com雖然對于默認的對象書寫方式有類型推導支持,但里面的實現繞了很多彎。愛掏網 - it200.com問題的本質其實很簡單:因為當初 API 的設計根本就沒有考慮類型系統。愛掏網 - it200.com
Vue 五年半以前剛開始寫的時候,JS 根本沒有類型系統,我自己當時也不用帶類型的語言,所以 Vue 的組件本質上就是一個 “包含了描述組件選項的對象”。愛掏網 - it200.com
這個設計算是一個典型的 intuition based design,它不是從語言本身的機制或是類型系統出發去設計的,而是單純從人如何描述自己想要的東西出發的。愛掏網 - it200.com這樣的設計的好處是對于新手很容易理解,缺陷是跟類型系統之間確實存在一定的 “斷層”。愛掏網 - it200.com這個斷層的意義到底有多大,對于不同類型的用戶其實不太一樣。愛掏網 - it200.com首先,因為 API 還算簡單直白,所以即使和傳統的 OO 有一定的 mismatch,但大部分人適應起來還是很快。愛掏網 - it200.com對于不使用類型系統,更關注組件業務邏輯的用戶來說,這個斷層其實是感受不到的。愛掏網 - it200.com
其次,這里的斷層其實是雙向的:你可以說是 Vue 的 API 設計不 type friendly,反過來也可以說是 TS 的類型系統不夠強大所以沒法給 Vue 提供足夠好的支持。愛掏網 - it200.com一個例子就是 JSX 其實一開始也沒有類型支持,完全是 TS 強行給加了一整套針對 JSX 的推導機制才給了 TSX 現在的開發體驗。愛掏網 - it200.com如果 TS 因為 JSX 不屬于真正的 JS 規范因而不提供支持,是不是也可以說 React 的設計跟類型系統存在斷層?
當然想要抹平這個斷層,更直接的辦法是對 API 進行重新設計。愛掏網 - it200.com這話說起來很簡單,但對于 Vue 來說,改 API 需要考慮很多東西:
跟原有 API 的兼容性:能否同時支持新舊 API?舊的用戶如何升級?像 Angular 那樣直接改得面目全非當然比較簡單,但說直接點就是不管舊版本用戶的死活;
如何設計出既能提供良好的類型推導,又不讓為了類型而做的設計 leak 到非 TS 用戶的使用體驗中去?如何在 TS 和非 TS 的使用體驗之間做到最好的一致性和平衡?Again,像 Angular 那樣不管非 TS 的用戶的死活當然也是比較簡單,但我們不會這么做。愛掏網 - it200.com
class 的原生支持不理想:如果太早用 class 作為默認的 API,那么意味著用戶不預編譯就無法在一部分瀏覽器中使用,這是我們一直極力避免的情況。愛掏網 - it200.comVue 一直很重視 “引入一個 script 就可以開始寫” 這樣的用例,因為這保證了新人上手的最低門檻,也讓 Vue 可以很簡單的整合到 legacy 應用當中作為 jQuery 的替代品。愛掏網 - it200.com所以要改 API 有一個時機問題,太早了不合適。愛掏網 - it200.com
用 class 寫組件所依賴的 class fields, decorators 等提案尚不穩定:基于 stage\u0026lt;4 的提案設計 API 是非常具有風險的,比如大家一開始都默認 class fields 的語義是 [[Set]],結果到 stage 3 改成了 [[Define]],這下 Polymer 急死了,因為它們有一個 API 設計是完全依賴了 class fields 的 [[Set]] 語義的。愛掏網 - it200.comdecorators 提案被徹底重新設計,并且在最近的 TC39 試圖升 stage 3 被 V8 團隊出于性能的考慮否決,可能又要大改;decorators 是否能放在 export 前面依然還在爭論,為此 Angular 的老大 Igor 急的不行… 所以,如何避免設計出來的 API 在提案發生改動之后***也要改,陷自己于尷尬境地?Again,時機問題,等提案成熟,或是等有爭議的點有結論后再動手(雖說我其實也是被邀請參與了這些東西的討論的,但討論規范真的是超級費時費神,還往往說服不了幾個人…)。愛掏網 - it200.com
額外說說模版和類型推導的關系。愛掏網 - it200.com表面上看,隔了一層模版語法 + 編譯,似乎確實存在 “斷層”,但其實里面沒你想的差那么遠。愛掏網 - it200.comVue 的模版是編譯成 virtual dom 渲染函數的,生成的 js 跟 React 的渲染函數一樣可以類型推導,而模版跟生成的 js 之間是完整的邏輯映射,所以這里其實主要是需要做一些工具鏈上的銜接,把對生成的 js 分析出來的 intellisense 反饋到 IDE 里的模版上,技術上是完全可行的。愛掏網 - it200.com
高票答案有另一個地方說 React 的 js 本位使得它做多端渲染簡單,這話其實不對,做多端本質上是需要運行時一開始就做核心和平臺分離的設計,這一點 Vue 2 一開始就做了(所以才會有 weex, NativeScript Vue 等等),實際上有模版這個更簡單的編譯源,做多端靈活性還更高一點,現在用 Vue 做小程序多端的方案一點都不少啊,mpvue, megalo, uni-app…
至于 Vue 本身使用什么類型系統做內部實現,其實是另一個問題了。愛掏網 - it200.com用戶用 TS 寫 Vue 的體驗關鍵還是在 API,用 TS 做內部實現其實只是減少了額外維護 d.ts 的成本。愛掏網 - it200.com
至于當初為什么沒用 TS,我之前的回答相信很多人都看過了,誰能想到 Flow 團隊會這么爛尾呢。愛掏網 - it200.com相比之下,TS 團隊確實是在用心做事的。愛掏網 - it200.com
總結一下:
現有的 API 和類型系統的結合存在缺陷,屬于歷史遺留;改新的 API 有個時機問題,請耐心等待 Vue 3;
TSX 類型支持好是因為 TS 專門開了后門給做了支持;模版只要工具鏈到位一樣可以做到;
Vue 2 一開始內部實現就有類型系統,但是沒想到 Flow 爛尾了,而 TS 整個生態越做越好。愛掏網 - it200.com
更多內容,請關注前端之巔。愛掏網 - it200.com
會議推薦
2024年6月,GMTC全球大前端技術大會2024即將到來。愛掏網 - it200.com小程序、Flutter、移動AI、工程化、性能優化…大前端的下一站在哪里?點擊下圖了解更多詳情。愛掏網 - it200.com