TypeScript培養(yǎng)類型思維
前言:當(dāng)你點(diǎn)開這篇文章時,我相信你已經(jīng)在很多地方都已經(jīng)聽說過或者見過TypeScript了。
但是可能對TypeScript依然有很多問號:TypeScript到底是什么?為什么每個人都在說TypeScript怎么怎么好,到底好在哪里?Angular、Vue3接連使用TypeScript進(jìn)行了重構(gòu)是否意味著我們必須掌握TypeScript,它們又為什么要選擇TypeScript?我需要什么樣的基礎(chǔ)才能學(xué)會或者說學(xué)好TypeScript呢?
沒有關(guān)系,在這個章節(jié)中我們就來解答上面的疑惑,并且我希望大家學(xué)完這個章節(jié)可以對一個概念有深入的理解,就是類型思維。
不著急,下面就讓我們和TypeScript有一場美麗的邂逅~
一. JavaScript的痛點(diǎn)
我始終堅(jiān)信:任何新技術(shù)的出現(xiàn)都是為了解決之前某個技術(shù)的痛點(diǎn)。
1.1. 優(yōu)秀的JavaScript
JavaScript是一門優(yōu)秀的編程語言嗎?
?每個人可能觀點(diǎn)并不完全一致,但是從很多角度來看,JavaScript是一門非常優(yōu)秀的編程語言。
?而且,可以說在很長一段時間內(nèi)這個語言不會被代替,并且會在更多的領(lǐng)域被大家廣泛使用。
著名的Atwood定律:
?Stack Overflow的創(chuàng)立者之一的?Jeff Atwood?在2007年提出了著名的?Atwood定律。
?any application that can be written in JavaScript, will eventually be written in JavaScript.
?任何可以使用JavaScript來實(shí)現(xiàn)的應(yīng)用都最終都會使用JavaScript實(shí)現(xiàn)。
?其實(shí)我們已經(jīng)看到了,至少目前JavaScript在瀏覽器端依然無可替代,并且在服務(wù)端(Nodejs)也在備廣泛的應(yīng)用。
優(yōu)秀的JavaScript沒有缺點(diǎn)嗎?
?其實(shí)上由于各種歷史因素,JavaScript語言本身存在很多的缺點(diǎn);
?比如ES5以及之前的使用的var關(guān)鍵字關(guān)于作用域的問題;
?比如最初JavaScript設(shè)計(jì)的數(shù)組類型并不是連續(xù)的內(nèi)存空間;
?比如直到今天JavaScript也沒有加入類型檢測這一機(jī)制;
JavaScript正在慢慢變好
?不可否認(rèn)的是,JavaScript正在慢慢變得越來越好,無論是從底層設(shè)計(jì)還是應(yīng)用層面。
?ES6、7、8等的推出,每次都會讓這門語言更加現(xiàn)代、更加安全、更加方便。
?但是知道今天,JavaScript在類型檢測上依然是毫無進(jìn)展(為什么類型檢測如此重要,我后面會聊到)。
1.2. 類型引發(fā)的問題
首先你需要知道,編程開發(fā)中我們有一個共識:錯誤出現(xiàn)的越早越好
?能在寫代碼的時候發(fā)現(xiàn)錯誤,就不要在代碼編譯時再發(fā)現(xiàn)(IDE的優(yōu)勢就是在代碼編寫過程中幫助我們發(fā)現(xiàn)錯誤)。
?能在代碼編譯期間發(fā)現(xiàn)錯誤,就不要在代碼運(yùn)行期間再發(fā)現(xiàn)(類型檢測就可以很好的幫助我們做到這一點(diǎn))。
?能在開發(fā)階段發(fā)現(xiàn)錯誤,就不要在測試期間發(fā)現(xiàn)錯誤,能在測試期間發(fā)現(xiàn)錯誤,就不要在上線后發(fā)現(xiàn)錯誤。
現(xiàn)在我們想探究的就是如何在?代碼編譯期間?發(fā)現(xiàn)代碼的錯誤:
?JavaScript可以做到嗎?不可以,我們來看下面這段經(jīng)常可能出現(xiàn)的代碼問題。
function getLength(str) {
? return str.length;
}
console.log("1.正在的代碼執(zhí)行");
console.log("2.開始函數(shù)");
getLength("abc"); // 正確的調(diào)用
getLength(); // 錯誤的調(diào)用(IDE并不會報(bào)錯)
// 當(dāng)上面的代碼報(bào)錯后, 后續(xù)所有的代碼都無法繼續(xù)正常執(zhí)行了
console.log("3.調(diào)用結(jié)束");

在瀏覽器下的運(yùn)行結(jié)果如下:

這是我們一個非常常見的錯誤:
?這個錯誤很大的原因就是因?yàn)镴avaScript沒有對我們傳入的參數(shù)進(jìn)行任何的限制,只能等到運(yùn)行期間才發(fā)現(xiàn)這個錯誤;
?并且當(dāng)這個錯誤產(chǎn)生時,會影響后續(xù)代碼的繼續(xù)執(zhí)行,也就是整個項(xiàng)目都因?yàn)橐粋€小小的錯誤而深入崩潰;
Uncaught TypeError: Cannot read property 'length' of undefined
當(dāng)然,你可能會想:我怎么可能犯這樣低級的錯誤呢?
?當(dāng)我們寫像我們上面這樣的簡單的demo時,這樣的錯誤很容易避免,并且當(dāng)出現(xiàn)錯誤時,也很容易檢查出來;
?但是當(dāng)我們開發(fā)一個大型項(xiàng)目時呢?你能保證自己一定不會出現(xiàn)這樣的問題嗎?而且如果我們是調(diào)用別人的類庫,又如何知道讓我們傳入的到底是什么樣的參數(shù)呢?
但是,如果我們可以給JavaScript加上很多限制,在開發(fā)中就可以很好的避免這樣的問題了:
?比如我們的getLength函數(shù)中str是一個必傳的類型,沒有調(diào)用者沒有傳編譯期間就會報(bào)錯;
?比如我們要求它的必須是一個String類型,傳入其他類型就直接報(bào)錯;
?那么就可以知道很多的錯誤問題在編譯期間就被發(fā)現(xiàn),而不是等到運(yùn)行時再去發(fā)現(xiàn)和修改;
1.3. 類型思維的缺失
?我們已經(jīng)簡單體會到?jīng)]有類型檢查帶來的一些問題,JavaScript因?yàn)閺脑O(shè)計(jì)之初就沒有考慮類型的約束問題,所以造成了前端開發(fā)人員關(guān)于類型思維的缺失:
?前端開發(fā)人員通常不關(guān)心變量或者參數(shù)是什么類型的,如果在必須確定類型時,我們往往需要使用各種判斷驗(yàn)證;
?從其他方向轉(zhuǎn)到前端的人員,也會因?yàn)闆]有類型約束,而總是擔(dān)心自己的代碼不安全,不夠健壯;
?所以我們經(jīng)常會說JavaScript不適合開發(fā)大型項(xiàng)目,因?yàn)楫?dāng)項(xiàng)目一旦龐大起來,這種寬松的類型約束會帶來非常多的安全隱患,多人員開發(fā)它們之間也沒有良好的類型契約。
?比如當(dāng)我們?nèi)?shí)現(xiàn)一個核心類庫時,如果沒有類型約束,那么需要對別人傳入的參數(shù)進(jìn)行各種驗(yàn)證來保證我們代碼的健壯性;
?比如我們?nèi)フ{(diào)用別人的函數(shù),對方?jīng)]有對函數(shù)進(jìn)行任何的注釋,我們只能去看里面的邏輯來理解這個函數(shù)需要傳入什么參數(shù),返回值是什么類型。
?為了彌補(bǔ)JavaScript類型約束上的缺陷,增加類型約束,很多公司推出了自己的方案:
?2014年,F(xiàn)acebook推出了flow來對JavaScript進(jìn)行類型檢查;
?同年,Microsoft微軟也推出了TypeScript1.0版本;
?他們都致力于為JavaScript提供類型檢查;
?而現(xiàn)在,無疑TypeScript已經(jīng)完全勝出:
?Vue2.x的時候采用的就是flow來做類型檢查;
?Vue3.x已經(jīng)全線轉(zhuǎn)向TypeScript,98.3%使用TypeScript進(jìn)行了重構(gòu);
?而Angular在很早期就使用TypeScript進(jìn)行了項(xiàng)目重構(gòu)并且需要使用TypeScript來進(jìn)行開發(fā);
?而甚至Facebook公司一些自己的產(chǎn)品也在使用TypeScript;
?學(xué)習(xí)TypeScript不僅僅可以為我們的代碼增加類型約束,而且可以培養(yǎng)我們前端程序員具備類型思維。
?下面就讓我們今天的主角TypeScript隆重登場吧!
二. 邂逅TypeScript
2.1. 什么是TypeScript
雖然我們已經(jīng)知道TypeScript是干什么的了,也知道它解決了什么樣的問題,但是我們還是需要全面的來認(rèn)識一下TypeScript到底是什么?
我們來看一下TypeScript在GitHub和官方上對自己的定義:
GitHub說法:TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
TypeScript官網(wǎng):TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
翻譯一下:TypeScript是擁有類型的JavaScript超集,它可以編譯成普通、干凈、完整的JavaScript代碼。
怎么理解上面的話呢?
?我們可以將TypeScript理解成加強(qiáng)版的JavaScript。
?JavaScript所擁有的特性,TypeScript全部都是支持的,并且它緊隨ECMAScript的標(biāo)準(zhǔn),所以ES6、ES7、ES8等新語法標(biāo)準(zhǔn),它都是支持的;
?并且在語言層面上,不僅僅增加了類型約束,而且包括一些語法的擴(kuò)展,比如枚舉類型(Enum)、元組類型(Tuple)等;
?TypeScript在實(shí)現(xiàn)新特性的同時,總是保持和ES標(biāo)準(zhǔn)的同步甚至是領(lǐng)先;
?并且TypeScript最終會被編譯成JavaScript代碼,所以你并不需要擔(dān)心它的兼容性問題,在編譯時也不需要借助于Babel這樣的工具;
所以,我們可以把TypeScript理解成一身神裝的JavaScript,不僅讓JavaScript更加安全,而且給它帶來了諸多好用的裝備特效;
2.2. TypeScript的特點(diǎn)
官方對TypeScript有幾段特點(diǎn)的描述,我覺得非常到位(雖然有些官方,了解一下),我們一起來分享一下:
始于JavaScript,歸于JavaScript
?
TypeScript從今天數(shù)以百萬計(jì)的JavaScript開發(fā)者所熟悉的語法和語義開始。使用現(xiàn)有的JavaScript代碼,包括流行的JavaScript庫,并從JavaScript代碼中調(diào)用TypeScript代碼。
?
?
TypeScript可以編譯出純凈、 簡潔的JavaScript代碼,并且可以運(yùn)行在任何瀏覽器上、Node.js環(huán)境中和任何支持ECMAScript 3(或更高版本)的JavaScript引擎中。
?
TypeScript是一個強(qiáng)大的工具,用于構(gòu)建大型項(xiàng)目
?
類型允許JavaScript開發(fā)者在開發(fā)JavaScript應(yīng)用程序時使用高效的開發(fā)工具和常用操作比如靜態(tài)檢查和代碼重構(gòu)。
?
?
類型是可選的,類型推斷讓一些類型的注釋使你的代碼的靜態(tài)驗(yàn)證有很大的不同。類型讓你定義軟件組件之間的接口和洞察現(xiàn)有JavaScript庫的行為。
?
擁有先進(jìn)的 JavaScript
?
TypeScript提供最新的和不斷發(fā)展的JavaScript特性,包括那些來自2015年的ECMAScript和未來的提案中的特性,比如異步功能和Decorators,以幫助建立健壯的組件。
?
?
這些特性為高可信應(yīng)用程序開發(fā)時是可用的,但是會被編譯成簡潔的ECMAScript3(或更新版本)的JavaScript。
?
正是因?yàn)橛羞@些特性,TypeScript目前已經(jīng)在很多地方被應(yīng)用:
?包括我們前面提到的Vue3和Angular已經(jīng)使用TypeScript進(jìn)行重構(gòu);

?
vue3源碼

angular源碼
?包括Vue3以后的開發(fā)模式必然會和TypeScript更加切合,大家也更多的需要使用TypeScript來編寫代碼;
?包括目前已經(jīng)變成最流行的編輯器VSCode也是使用TypeScript來完成的
?

?包括在React中已經(jīng)使用的ant-design的UI庫,也大量使用TypeScript來編寫:

ant-design源碼
?包括小程序開發(fā),也是支持TypeScript的

小程序開發(fā)
2.3. 體驗(yàn)TypeScript
本來想在這個位置放上一個體驗(yàn)TypeScript的程序,但是涉及到過多TypeScript的安裝流程和vscode的配置信息。
所以,我打算在下一篇中專門講解這部分的內(nèi)容,包括使用webpack搭建一個可以自動測試TypeScript代碼的環(huán)境。
So,稍安勿躁,這一個章節(jié)我們就和TypeScript有一個簡單的邂逅就好,后面再進(jìn)行深入了解。
三. 前端學(xué)不動系列
3.1. 前端開發(fā)者的難
在之前的Flutter文章中,我說到一個話題,大前端是一群最能或者說最需要折騰的開發(fā)者:
?客戶端開發(fā)者:從Android到iOS,或者從iOS到Android,到RN,甚至現(xiàn)在越來越多的客戶端開發(fā)者接觸前端相關(guān)知識(Vue、React、Angular、小程序);
?前端開發(fā)者:從jQuery到AngularJS,到三大框架并行:Vue、React、Angular,還有小程序,甚至現(xiàn)在也要接觸客戶端開發(fā)(比如RN、Flutter);
?目前又面臨著不僅僅學(xué)習(xí)ES的特性,還要學(xué)習(xí)TypeScript;
?Vue3馬上也會到來,又必須學(xué)習(xí)Vue3新特性;
大前端開發(fā)就是,不像服務(wù)器一樣可能幾年甚至幾十年還是那一套的東西。前端新技術(shù)會層出不窮。

但是每一樣技術(shù)的出現(xiàn)都會讓驚喜,因?yàn)樗厝皇墙鉀Q了之前技術(shù)的某一個痛點(diǎn)的,而TypeScript真是解決了JavaScript存在的很多設(shè)計(jì)缺陷,尤其是關(guān)于類型檢測的。
并且從開發(fā)者長遠(yuǎn)的角度來看,學(xué)習(xí)TypeScript有助于我們前端程序員培養(yǎng)?類型思維,這種思維方式對于完成大型項(xiàng)目尤為重要。
我也會更新一個TypeScript的系列文章,帶著大家一起來學(xué)習(xí)TypeScript,并且培養(yǎng)大家可以形成類型思維。
3.2. 解除心中的疑惑
回到我們開篇提出的一些疑惑:
TypeScript到底是什么?為什么每個人都在說TypeScript怎么怎么好,到底好在哪里?Angular、Vue3接連使用TypeScript進(jìn)行了重構(gòu)是否意味著我們必須掌握TypeScript,它們又為什么要選擇TypeScript?我需要什么樣的基礎(chǔ)才能學(xué)會或者說學(xué)好TypeScript呢?
看完文章,相信對于上面的問題,你心里應(yīng)該已經(jīng)有了答案,之后也會更新其他技術(shù)文章,如:TypeScript、React、Node、數(shù)據(jù)結(jié)構(gòu)與算法等等,也會更新一些自己的學(xué)習(xí)心得等,歡迎大家添加微信:19950277730,獲取更多干貨分享及學(xué)習(xí)資源。