TypeScript中d.ts類(lèi)型聲明文件的實(shí)現(xiàn)
1. 簡(jiǎn)介
單獨(dú)使用的模塊,一般會(huì)同時(shí)提供一個(gè)單獨(dú)的類(lèi)型聲明文件(declaration file),把本模塊的外部接口的所有類(lèi)型都寫(xiě)在這個(gè)文件里面,便于模塊使用者了解接口,也便于編譯器檢查使用者的用法是否正確。
類(lèi)型聲明文件里面只有類(lèi)型代碼,沒(méi)有具體的代碼實(shí)現(xiàn)。它的文件名一般為[模塊名].d.ts
的形式,其中的d
表示 declaration(聲明)。
例如:某個(gè)模塊
const maxInterval = 12; function getArrayLength(arr) { return arr.length; } module.exports = { getArrayLength, maxInterval, };
這個(gè)模塊的類(lèi)型聲明文件
export function getArrayLength(arr: any[]): number; export const maxInterval: 12;
在類(lèi)型聲明文件中,模塊輸出可以寫(xiě)成export=
或者export default
表示
// 模塊輸出 module.exports = 3.142; // 類(lèi)型輸出文件 // 寫(xiě)法一 declare const pi: number; export default pi; // 寫(xiě)法二 declare const pi: number; export= pi;
類(lèi)型聲明文件也可以寫(xiě)在項(xiàng)目的 tsconfig.json 文件里面,這樣的話(huà),編譯器打包項(xiàng)目時(shí),會(huì)自動(dòng)將類(lèi)型聲明文件加入編譯,而不必在每個(gè)腳本里面加載類(lèi)型聲明文件。比如,moment 模塊的類(lèi)型聲明文件是moment.d.ts
,使用 moment 模塊的項(xiàng)目可以將其加入項(xiàng)目的 tsconfig.json 文件。
{ "compilerOptions": {}, "files": [ "src/index.ts", "typings/moment.d.ts" ] }
2. 類(lèi)型聲明文件的來(lái)源
有三種來(lái)源:1. ts編譯器自動(dòng)生成 2. ts內(nèi)置類(lèi)型文件 3. 外部模塊的類(lèi)型聲明文件,需要自己安裝
1. ts編譯器自動(dòng)生成
只要使用編譯選項(xiàng)declaration
,編譯器就會(huì)在編譯時(shí)自動(dòng)生成單獨(dú)的類(lèi)型聲明文件。
下面是在tsconfig.json
文件里面,打開(kāi)這個(gè)選項(xiàng)。
{ "compilerOptions": { "declaration": true } }
你也可以在命令行打開(kāi)這個(gè)選項(xiàng)。
$ tsc --declaration
2. 內(nèi)置聲明文件
安裝 TypeScript 語(yǔ)言時(shí),會(huì)同時(shí)安裝一些內(nèi)置的類(lèi)型聲明文件,主要是內(nèi)置的全局對(duì)象(JavaScript 語(yǔ)言接口和運(yùn)行環(huán)境 API)的類(lèi)型聲明。
這些內(nèi)置文件存放在ts安裝目錄的lib文件夾內(nèi),文件名統(tǒng)一為lib.[description].d.ts
的形式,其中description
部分描述文件內(nèi)容,比如lib.dom.d.ts
文件就是描述了DOM結(jié)構(gòu)的類(lèi)型。
ts 編譯器會(huì)自動(dòng)根據(jù)編譯目標(biāo)target
的值,加載對(duì)應(yīng)的內(nèi)置聲明文件,所以不需要特別的配置。但是,可以使用編譯選項(xiàng)lib
,指定加載哪些內(nèi)置聲明文件。
{ "compilerOptions": { "lib": ["dom", "es2021"] } }
上面示例中,lib
選項(xiàng)指定加載dom
和es2021
這兩個(gè)內(nèi)置類(lèi)型聲明文件。編譯選項(xiàng)noLib
會(huì)禁止加載任何內(nèi)置聲明文件
3. 外部類(lèi)型聲明文件
如果項(xiàng)目中使用了外部的某個(gè)第三方代碼庫(kù),就需要這個(gè)庫(kù)的類(lèi)型聲明文件。
這時(shí)有分三種情況
- 這個(gè)庫(kù)自帶了類(lèi)型聲明文件。
一般來(lái)說(shuō),如果這個(gè)庫(kù)的源碼包含了[vendor].d.ts
文件,那么就自帶了類(lèi)型聲明文件。其中的vendor
表示這個(gè)庫(kù)的名字,比如moment
這個(gè)庫(kù)就自帶moment.d.ts
。使用這個(gè)庫(kù)可能需要單獨(dú)加載它的類(lèi)型聲明文件。
- 這個(gè)庫(kù)沒(méi)有自帶,但是可以找到社區(qū)制作的類(lèi)型聲明文件
第三方庫(kù)如果沒(méi)有提供類(lèi)型聲明文件,社區(qū)往往會(huì)提供。ts 社區(qū)主要使用 DefinitelyTyped 倉(cāng)庫(kù),各種類(lèi)型聲明文件都會(huì)提交到那里,已經(jīng)包含了幾千個(gè)第三方庫(kù)。
這些聲明文件都會(huì)作為一個(gè)單獨(dú)的庫(kù),發(fā)布到 npm 的@types
名稱(chēng)空間之下。比如,jQuery 的類(lèi)型聲明文件就發(fā)布成@types/jquery
這個(gè)庫(kù),使用時(shí)安裝這個(gè)庫(kù)就可以了。
$ npm install @types/jquery --save-dev
執(zhí)行上面的命令,@types/jquery
這個(gè)庫(kù)就安裝到項(xiàng)目的node_modules/@types/jquery
目錄,里面的index.d.ts
文件就是 jQuery 的類(lèi)型聲明文件。如果類(lèi)型聲明文件不是index.d.ts
,那么就需要在package.json
的types
或typings
字段,指定類(lèi)型聲明文件的文件名。
ts 會(huì)自動(dòng)加載node_modules/@types
目錄下的模塊,但可以使用編譯選項(xiàng)typeRoots
改變這種行為。
{ "compilerOptions": { "typeRoots": ["./typings", "./vendor/types"] } }
上面示例表示,ts 不再去node_modules/@types
目錄,而是去跟當(dāng)前tsconfig.json
同級(jí)的typings
和vendor/types
子目錄,加載類(lèi)型模塊了。
默認(rèn)情況下,ts會(huì)自動(dòng)加載typeRoots
目錄里的所有模塊,編譯選項(xiàng)types
可以指定加載哪些模塊。
{ "compilerOptions": { "types" : ["jquery"] } }
上面設(shè)置中,types
屬性是一個(gè)數(shù)組,成員是所要加載的類(lèi)型模塊,要加載幾個(gè)模塊,這個(gè)數(shù)組就有幾個(gè)成員,每個(gè)類(lèi)型模塊在typeRoots
目錄下都有一個(gè)自己的子目錄。這樣的話(huà),TypeScript 就會(huì)自動(dòng)去jquery
子目錄,加載 jQuery 的類(lèi)型聲明文件。
- 找不到類(lèi)型聲明文件,需要自己寫(xiě)
有時(shí)實(shí)在沒(méi)有第三方庫(kù)的類(lèi)型聲明文件,又很難完整給出該庫(kù)的類(lèi)型描述,這時(shí)你可以告訴 ts 相關(guān)對(duì)象的類(lèi)型是any
。比如,使用 jQuery 的腳本可以寫(xiě)成下面這樣。
declare var $:any // 或者 declare type JQuery = any; declare var $:JQuery;
上面代碼表示,jQuery 的$
對(duì)象是外部引入的,類(lèi)型是any
,也就是 ts 不用對(duì)它進(jìn)行類(lèi)型檢查。
也可以采用下面的寫(xiě)法,將整個(gè)外部模塊的類(lèi)型設(shè)為any
。
declare module '模塊名';
有了上面的命令,指定模塊的所有接口都將視為any
類(lèi)型
3. declare關(guān)鍵字
類(lèi)型聲明文件只包含類(lèi)型描述,不包含具體實(shí)現(xiàn),所以非常適合使用declare語(yǔ)句來(lái)描述類(lèi)型。
類(lèi)型聲明文件里面,變量的類(lèi)型描述必須使用declare
命令,否則會(huì)報(bào)錯(cuò),因?yàn)樽兞柯暶髡Z(yǔ)句是值相關(guān)代碼。
declare let foo:string;
interface 類(lèi)型有沒(méi)有declare
都可以,因?yàn)?interface 是完全的類(lèi)型代碼。
interface Foo {} // 正確 declare interface Foo {} // 正確
類(lèi)型聲明文件里面,頂層可以使用export
命令,也可以不用,除非使用者腳本會(huì)顯式使用export
命令輸入類(lèi)型。
export interface Data { version: string; }
4. 模塊發(fā)布
當(dāng)前模塊如果包含自己的類(lèi)型聲明文件,可以在 package.json 文件里面添加一個(gè)types
字段或typings
字段,指明類(lèi)型聲明文件的位置。
{ "name": "awesome", "author": "Vandelay Industries", "version": "1.0.0", "main": "./lib/main.js", "types": "./lib/main.d.ts" }
如果類(lèi)型聲明文件名為index.d.ts
,且在項(xiàng)目的根目錄中,那就不需要在package.json
里面注明了。
有時(shí),類(lèi)型聲明文件會(huì)單獨(dú)發(fā)布成一個(gè) npm 模塊,這時(shí)就必須同時(shí)加載該模塊。
這是一個(gè)模塊的 package.json 文件,該模塊需要 browserify 模塊。由于后者的類(lèi)型聲明文件是一個(gè)單獨(dú)的模塊@types/browserify
,所以還需要加載那個(gè)單獨(dú)的模塊(類(lèi)型聲明是個(gè)單獨(dú)模塊)。
{ "name": "browserify-typescript-extension", "author": "Vandelay Industries", "version": "1.0.0", "main": "./lib/main.js", "types": "./lib/main.d.ts", "dependencies": { "browserify": "latest", "@types/browserify": "latest", "typescript": "next" } }
5. 三斜桿命令
如果類(lèi)型聲明文件的內(nèi)容特別多,可以拆分成多個(gè)文件,然后再入口文件使用三斜桿命令去加載拆分后的文件。
舉例來(lái)說(shuō),入口文件是main.d.ts
,里面的接口定義在interfaces.d.ts
,函數(shù)定義在functions.d.ts
。那么,main.d.ts
里面可以用三斜杠命令,加載后面兩個(gè)文件。
// main.d.ts文件 /// <reference path="./interfaces.d.ts" /> /// <reference path="./functions.d.ts" />
三斜杠命令(///
)是一個(gè) ts 編譯器命令,用來(lái)指定編譯器行為。它只能用在文件的頭部,如果用在其他地方,會(huì)被當(dāng)作普通的注釋。另外,若一個(gè)文件中使用了三斜線(xiàn)命令,那么在三斜線(xiàn)命令之前只允許使用單行注釋、多行注釋和其他三斜線(xiàn)命令,否則三斜杠命令也會(huì)被當(dāng)作普通的注釋。
除了拆分類(lèi)型聲明文件,三斜杠命令也可以用于普通腳本加載類(lèi)型聲明文件。
三斜桿命令有三個(gè)參數(shù),代表不同的命令。path、types、lib
1. ///<reference path=“”>
告訴編譯器在編譯時(shí)需要包括的文件,來(lái)聲明當(dāng)前腳本依賴(lài)的類(lèi)型文件。編譯器會(huì)在預(yù)處理階段,找出所有三斜杠引用的文件,將其添加到編譯列表中,然后一起編譯。
/// <reference path="./lib.ts" /> let count = add(1, 2);
上面示例表示,當(dāng)前腳本依賴(lài)于./lib.ts
,里面是add()
的定義。編譯當(dāng)前腳本時(shí),還會(huì)同時(shí)編譯./lib.ts
。編譯產(chǎn)物會(huì)有兩個(gè) JS 文件,一個(gè)當(dāng)前腳本,另一個(gè)就是./lib.js
。
path
參數(shù)指定了所引入文件的路徑。如果該路徑是一個(gè)相對(duì)路徑,則基于當(dāng)前腳本的路徑進(jìn)行計(jì)算。
使用該命令時(shí),有以下兩個(gè)注意事項(xiàng)。
path
參數(shù)必須指向一個(gè)存在的文件,若文件不存在會(huì)報(bào)錯(cuò)。path
參數(shù)不允許指向當(dāng)前文件。
默認(rèn)情況下,每個(gè)三斜杠命令引入的腳本,都會(huì)編譯成單獨(dú)的 JS 文件。如果希望編譯后只產(chǎn)出一個(gè)合并文件,可以使用編譯選項(xiàng)outFile
。但是,outFile
編譯選項(xiàng)不支持合并 CommonJS 模塊和 ES 模塊,只有當(dāng)編譯參數(shù)module
的值設(shè)為 None、System 或 AMD 時(shí),才能編譯成一個(gè)文件。
如果打開(kāi)了編譯參數(shù)noResolve
,則忽略三斜杠指令。將其當(dāng)作一般的注釋?zhuān)瓨颖A粼诰幾g產(chǎn)物中。
2. /// <reference types=“” />
types參數(shù)用來(lái)告訴編譯器當(dāng)前腳本依賴(lài)某個(gè)DefinitelyTyped 類(lèi)型庫(kù),通常安裝在node_modules/@types
目錄。
types 參數(shù)的值是類(lèi)型庫(kù)的名稱(chēng),也就是安裝到node_modules/@types
目錄中的子目錄的名字。
/// <reference types="node" />
上面例子中,這個(gè)三斜杠命令表示編譯時(shí)添加 Node.js 的類(lèi)型庫(kù),實(shí)際添加的腳本是node_modules
目錄里面的@types/node/index.d.ts
。
可以看到,這個(gè)命令的作用類(lèi)似于import
命令。
注意,這個(gè)命令只在你自己手寫(xiě)類(lèi)型聲明文件(.d.ts
文件)時(shí),才有必要用到,也就是說(shuō),只應(yīng)該用在.d.ts
文件中,普通的.ts
腳本文件不需要寫(xiě)這個(gè)命令。如果是普通的.ts
腳本,可以使用tsconfig.json
文件的types
屬性指定依賴(lài)的類(lèi)型庫(kù)。
3. /// <reference lib=“” />
/// <reference lib="..." />
命令允許腳本文件顯式包含內(nèi)置 lib 庫(kù),等同于在tsconfig.json
文件里面使用lib
屬性指定 lib 庫(kù)。
安裝 ts 軟件包時(shí),會(huì)同時(shí)安裝一些內(nèi)置的類(lèi)型聲明文件,即內(nèi)置的 lib 庫(kù)。這些庫(kù)文件位于 ts 安裝目錄的lib
文件夾中,它們描述了 JavaScript 語(yǔ)言和引擎的標(biāo)準(zhǔn) API。
庫(kù)文件并不是固定的,會(huì)隨著 ts 版本的升級(jí)而更新。庫(kù)文件統(tǒng)一使用“lib.[description].d.ts”的命名方式,而/// <reference lib="" />
里面的lib
屬性的值就是庫(kù)文件名的description
部分,比如lib="es2015"
就表示加載庫(kù)文件lib.es2015.d.ts
。
/// <reference lib="es2017.string" />
上面例子中,es2017.string
對(duì)應(yīng)的庫(kù)文件就是lib.es2017.string.d.ts
。
到此這篇關(guān)于TypeScript中d.ts類(lèi)型聲明文件的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)TypeScript d.ts類(lèi)型聲明文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- typescript返回值類(lèi)型和參數(shù)類(lèi)型的具體使用
- Typescript中函數(shù)類(lèi)型及示例詳解
- typescript類(lèi)型體操及關(guān)鍵字使用示例詳解
- TypeScript中類(lèi)型映射的使用
- TypeScript中的類(lèi)型運(yùn)算符實(shí)現(xiàn)
- TypeScript基本類(lèi)型 typeof 和keyof案例詳解
- 淺聊一下TypeScript中的4種類(lèi)型守衛(wèi)
- typescript?type類(lèi)型使用梳理總結(jié)
- TypeScript 獲取函數(shù)的參數(shù)類(lèi)型、返回值類(lèi)型及定義返回函數(shù)類(lèi)型
相關(guān)文章
微信小程序開(kāi)發(fā)之map地圖組件定位并手動(dòng)修改位置偏差
這篇文章主要介紹了微信小程序開(kāi)發(fā)之map地圖組件,定位,并手動(dòng)修改位置偏差,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08js中substr,substring,indexOf,lastIndexOf的用法小結(jié)
本篇文章主要是對(duì)js中substr,substring,indexOf,lastIndexOf的用法進(jìn)行了總結(jié)介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-12-12JS實(shí)現(xiàn)網(wǎng)頁(yè)滾動(dòng)條感應(yīng)鼠標(biāo)變色的方法
這篇文章主要介紹了JS實(shí)現(xiàn)網(wǎng)頁(yè)滾動(dòng)條感應(yīng)鼠標(biāo)變色的方法,實(shí)例分析了javascript針對(duì)鼠標(biāo)事件的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02基于Bootstrap實(shí)現(xiàn)下拉菜單項(xiàng)和表單導(dǎo)航條(兩個(gè)菜單項(xiàng),一個(gè)下拉菜單和登錄表單導(dǎo)航條)
這篇文章主要介紹了基于Bootstrap實(shí)現(xiàn)下拉菜單項(xiàng)和表單導(dǎo)航條(兩個(gè)菜單項(xiàng),一個(gè)下拉菜單和登錄表單導(dǎo)航條)的相關(guān)資料,需要的朋友可以參考下2016-07-07Js數(shù)組對(duì)象如何根據(jù)多個(gè)key值進(jìn)行分類(lèi)
這篇文章主要介紹了Js數(shù)組對(duì)象如何根據(jù)多個(gè)key值進(jìn)行分類(lèi),每周從 npm 下載?lodash.groupBy?的次數(shù)在 150 萬(wàn)到 200 萬(wàn)之間,很高興看到 JavaScript 填補(bǔ)了這些空白,讓我們的工作變得更加輕松,需要的朋友可以參考下2024-02-02JavaScript獲取并更改input標(biāo)簽name屬性的方法
這篇文章主要介紹了JavaScript獲取并更改input標(biāo)簽name屬性的方法,涉及javascript針對(duì)表單元素屬性的相關(guān)操作技巧,需要的朋友可以參考下2015-07-07JS實(shí)現(xiàn)簡(jiǎn)單九宮格抽獎(jiǎng)
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)簡(jiǎn)單九宮格抽獎(jiǎng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06JavaScript實(shí)現(xiàn)向OL列表內(nèi)動(dòng)態(tài)添加LI元素的方法
這篇文章主要介紹了JavaScript實(shí)現(xiàn)向OL列表內(nèi)動(dòng)態(tài)添加LI元素的方法,實(shí)例分析了javascript操作html元素的技巧,需要的朋友可以參考下2015-03-03Bootstrap Paginator分頁(yè)插件使用方法詳解
這篇文章主要為大家詳細(xì)介紹了Bootstrap Paginator分頁(yè)插件使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05