types 和 @types 是什么?
點(diǎn)擊藍(lán)色“腦洞前端”關(guān)注我喲
加個(gè)“星標(biāo)”,帶你揭開大前端的神秘面紗!
?這是腦洞前端第「103」篇原創(chuàng)文章
TypeScript 的學(xué)習(xí)資料非常多,其中也不乏很多優(yōu)秀的文章和教程。但是目前為止沒有一個(gè)我特別滿意的。原因有:
它們大多數(shù)沒有一個(gè)清晰的主線,而是按照 API 組織章節(jié)的,內(nèi)容在**邏輯上**比較零散。 大多是“講是什么,怎么用“,而不是”講為什么,講原理“。 大多數(shù)內(nèi)容比較枯燥,趣味性比較低。都是干巴巴的文字,沒有圖片,缺乏能夠引起強(qiáng)烈共鳴的例子。
因此我的想法是做一套不同市面上大多數(shù)的 TypeScript 學(xué)習(xí)教程。以人類認(rèn)知的角度思考問題,學(xué)習(xí) TypeScript,通過通俗易懂的例子和圖片來幫助大家建立 TypeScript 世界觀。
系列安排:
上帝視角看 TypeScript(已發(fā)布) TypeScript 類型系統(tǒng)(已發(fā)布) types 和 @types 是什么?(就是本文) 你不知道的 TypeScript 泛型(萬字長(zhǎng)文,建議收藏)(已發(fā)布) TypeScript 配置文件該怎么寫? TypeScript 是如何與 React,Vue,Webpack 集成的? TypeScript 練習(xí)題
?目錄將來可能會(huì)有所調(diào)整。
?
注意,我的系列文章基本不會(huì)講 API,因此需要你有一定的 TypeScript 使用基礎(chǔ),推薦兩個(gè)學(xué)習(xí)資料。
深入理解 TypeScript 官方文檔
結(jié)合這兩個(gè)資料和我的系列教程,掌握 TypeScript 指日可待。
接下來,我們通過幾個(gè)方面來從宏觀的角度來看一下 TypeScript。
前言
作者:feiker & Lucifer
TypeScript 中有幾個(gè)概念和名字很像,會(huì)讓初學(xué)者傻傻分不清楚。比如配置文件中的 「types 和 typeRoots」,并且還有一個(gè) @types。接觸過 TypeScript 的人一定接觸過它們, 這幾個(gè)有什么區(qū)別和聯(lián)系呢?今天就帶你來重新認(rèn)識(shí)下它們。
一個(gè)例子
這里我通過一個(gè)例子來說明一下什么是 @types,這樣大家理解起來更深刻一點(diǎn)。
當(dāng)我們用 npm 等包管理工具安裝第三方包的時(shí)候,有些包并不是 TypeScript 編寫的,自然也不會(huì)導(dǎo)出 TypeScript 聲明文件。這種情況下,如果我們?cè)?TypeScript 項(xiàng)目中引入了這種包,則會(huì)編譯報(bào)錯(cuò)(沒有設(shè)置 allowJS)。舉個(gè)例子,當(dāng)我們通過npm install jquery --save 安裝 jquery 包并引用的時(shí)候,TypeScript 會(huì)報(bào)錯(cuò)。
?allowJS 是 TypeScript 1.8 引進(jìn)的一個(gè)編譯項(xiàng)。
?
報(bào)錯(cuò)內(nèi)容如下:
?Could not find a declaration file for module ‘jquery’. Try
?npm install @types/jqueryif it exists or add a new declaration (.d.ts) file containingdeclare module 'jquery';
這里的意思是 TypeScript 沒有找到 jquery 這個(gè)包的定義,你可以通過npm install @types/jquery安裝相關(guān)聲明,或者自己定義一份.d.ts 文件,并將 jquery 聲明為 module。
全世界不是 TypeScript 編寫的包多了去了。即使你的包是 TypeScript 編寫的,如果你沒有導(dǎo)出聲明文件,也是沒用的。(TypeScript 默認(rèn)不會(huì)導(dǎo)出聲明文件,只會(huì)編譯輸出 JavaScript 文件)。因此 TypeScript 必須對(duì)這種情況提供解決方案,而上面的兩種方案(安裝 @types 和 自己 declare module)就是 TypeScript 官方提出的, 你可以選擇適合你的方案。我的推薦是盡量使用 @types 下的聲明,實(shí)在沒有,再使用第二種方法。
值得一提的是,并不是所有的包都可以通過這種方式解決的, 能解決的是 DefinitelyTyped 組織已經(jīng)寫好定義的包, 好消息是比較流行的包基本都有。如果你想查一個(gè)包是否在 @type 下,可以訪問 https://microsoft.github.io/TypeSearch/
那么 TypeScript 是怎么找定義的,什么情況會(huì)找不到定義而報(bào)類似上面舉的例子的錯(cuò)誤,這里簡(jiǎn)單介紹下原理。
包類型定義的查找
就好像 node 的包查找是先在當(dāng)前文件夾找 node_modules,在它下找遞歸找,如果找不到則往上層目錄繼續(xù)找,直到頂部一樣, TypeScript 類型查找也是類似的方式。
具體來說就是:
TypeScript 編譯器先在當(dāng)前編譯上下文找 jquery 的定義。 如果找不到,則會(huì)去 node_modules 中的@types (默認(rèn)情況,目錄可以修改,后面會(huì)提到)目錄下去尋找對(duì)應(yīng)包名的模塊聲明文件。
??
@types/*模塊聲明文件由社區(qū)維護(hù),通過發(fā)布到@types 空間下。GitHub - DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions.
變量類型定義的查找
和包查找類似,默認(rèn)情況下變量類型定義的查找也會(huì)去 @types 下去尋找。只不過并不是直接去 @types 找,而是有一定的優(yōu)先級(jí), 這個(gè)過程類似原型鏈或者作用域鏈。
比如如下代碼:
const?user:?User?=?{?name:?"lucifer"?};
Typescript 則會(huì)先在本模塊查找 User 的定義。 如果找到,則直接返回。如果找不到, 則會(huì)到全局作用域找,而這個(gè)全局默認(rèn)就是指的就是 @types 下的所有類型定義。(注意目錄頁(yè)是可以配的)
?也就是說 @types 下的定義都是全局的。當(dāng)然你可以導(dǎo)入 @types 下導(dǎo)出的定義,使得它們的作用域變成你的模塊內(nèi)部。
?
typeRoots 與 types
前面說了 TypeScript 會(huì)默認(rèn)引入node_modules下的所有@types聲明,但是開發(fā)者也可以通過修改tsconfig.json的配置來修改默認(rèn)的行為.
tsconfig.json 中有兩個(gè)配置和類型引入有關(guān)。
typeRoots: 用來指定默認(rèn)的類型聲明文件查找路徑,默認(rèn)為node_modules/@types, 指定typeRoots后,TypeScript 編譯器會(huì)從指定的路徑去引入聲明文件,而不是node_modules/@types, 比如以下配置會(huì)從typings路徑下去搜索聲明
{
??"compilerOptions":?{
????"typeRoots":?["./typings"]
??}
}
types: TypeScript 編譯器會(huì)默認(rèn)引入typeRoot下所有的聲明文件,但是有時(shí)候我們并**不希望全局引入所有定義**,而是僅引入部分模塊。這種情景下可以通過types指定模塊名只引入我們想要的模塊,比如以下只會(huì)引入 jquery 的聲明文件
{
??"compilerOptions":?{
????"types":?["jquery"]
??}
}
總結(jié)
typeRoots 是 tsconfig 中 compilerOptions 的一個(gè)配置項(xiàng),typeRoots 下面的包會(huì)被 ts 編譯器自動(dòng)包含進(jìn)來,typeRoots 默認(rèn)指向 node_modules/@types。 @types 是 npm 的 scope 命名空間,和@babel 類似,@types 下的所有包會(huì)默認(rèn)被引入,你可以通過修改 compilerOptions 來修改默認(rèn)策略。 types 和 typeRoots 一樣也是 compilerOptions 的配置,指定 types 后,typeRoots 下只有被指定的包才會(huì)被引入。
參考
GitHub - DefinitelyTyped/DefinitelyTyped: The repository for high quality TypeScript type definitions. @types | 深入理解 TypeScript tsconfig.json · TypeScript 中文網(wǎng) · TypeScript——JavaScript 的超集 理解 Typescript 配置文件
推薦閱讀
1、力扣刷題插件
2、你不知道的 TypeScript 泛型(萬字長(zhǎng)文,建議收藏)
4、immutablejs 是如何優(yōu)化我們的代碼的?
6、想去力扣當(dāng)前端,TypeScript 需要掌握到什么程度?
?關(guān)注加加,星標(biāo)加加~
?
如果覺得文章不錯(cuò),幫忙點(diǎn)個(gè)在看唄
