TypeScript中d.ts類型聲明文件的實(shí)現(xiàn)
1. 簡介
單獨(dú)使用的模塊,一般會同時提供一個單獨(dú)的類型聲明文件(declaration file),把本模塊的外部接口的所有類型都寫在這個文件里面,便于模塊使用者了解接口,也便于編譯器檢查使用者的用法是否正確。
類型聲明文件里面只有類型代碼,沒有具體的代碼實(shí)現(xiàn)。它的文件名一般為[模塊名].d.ts的形式,其中的d表示 declaration(聲明)。
例如:某個模塊
const maxInterval = 12;
function getArrayLength(arr) {
return arr.length;
}
module.exports = {
getArrayLength,
maxInterval,
};
這個模塊的類型聲明文件
export function getArrayLength(arr: any[]): number; export const maxInterval: 12;
在類型聲明文件中,模塊輸出可以寫成export=或者export default表示
// 模塊輸出 module.exports = 3.142; // 類型輸出文件 // 寫法一 declare const pi: number; export default pi; // 寫法二 declare const pi: number; export= pi;
類型聲明文件也可以寫在項(xiàng)目的 tsconfig.json 文件里面,這樣的話,編譯器打包項(xiàng)目時,會自動將類型聲明文件加入編譯,而不必在每個腳本里面加載類型聲明文件。比如,moment 模塊的類型聲明文件是moment.d.ts,使用 moment 模塊的項(xiàng)目可以將其加入項(xiàng)目的 tsconfig.json 文件。
{
"compilerOptions": {},
"files": [
"src/index.ts",
"typings/moment.d.ts"
]
}
2. 類型聲明文件的來源
有三種來源:1. ts編譯器自動生成 2. ts內(nèi)置類型文件 3. 外部模塊的類型聲明文件,需要自己安裝
1. ts編譯器自動生成
只要使用編譯選項(xiàng)declaration,編譯器就會在編譯時自動生成單獨(dú)的類型聲明文件。
下面是在tsconfig.json文件里面,打開這個選項(xiàng)。
{
"compilerOptions": {
"declaration": true
}
}
你也可以在命令行打開這個選項(xiàng)。
$ tsc --declaration
2. 內(nèi)置聲明文件
安裝 TypeScript 語言時,會同時安裝一些內(nèi)置的類型聲明文件,主要是內(nèi)置的全局對象(JavaScript 語言接口和運(yùn)行環(huán)境 API)的類型聲明。
這些內(nèi)置文件存放在ts安裝目錄的lib文件夾內(nèi),文件名統(tǒng)一為lib.[description].d.ts的形式,其中description部分描述文件內(nèi)容,比如lib.dom.d.ts文件就是描述了DOM結(jié)構(gòu)的類型。
ts 編譯器會自動根據(jù)編譯目標(biāo)target的值,加載對應(yīng)的內(nèi)置聲明文件,所以不需要特別的配置。但是,可以使用編譯選項(xiàng)lib,指定加載哪些內(nèi)置聲明文件。
{
"compilerOptions": {
"lib": ["dom", "es2021"]
}
}
上面示例中,lib選項(xiàng)指定加載dom和es2021這兩個內(nèi)置類型聲明文件。編譯選項(xiàng)noLib會禁止加載任何內(nèi)置聲明文件
3. 外部類型聲明文件
如果項(xiàng)目中使用了外部的某個第三方代碼庫,就需要這個庫的類型聲明文件。
這時有分三種情況
- 這個庫自帶了類型聲明文件。
一般來說,如果這個庫的源碼包含了[vendor].d.ts文件,那么就自帶了類型聲明文件。其中的vendor表示這個庫的名字,比如moment這個庫就自帶moment.d.ts。使用這個庫可能需要單獨(dú)加載它的類型聲明文件。
- 這個庫沒有自帶,但是可以找到社區(qū)制作的類型聲明文件
第三方庫如果沒有提供類型聲明文件,社區(qū)往往會提供。ts 社區(qū)主要使用 DefinitelyTyped 倉庫,各種類型聲明文件都會提交到那里,已經(jīng)包含了幾千個第三方庫。
這些聲明文件都會作為一個單獨(dú)的庫,發(fā)布到 npm 的@types名稱空間之下。比如,jQuery 的類型聲明文件就發(fā)布成@types/jquery這個庫,使用時安裝這個庫就可以了。
$ npm install @types/jquery --save-dev
執(zhí)行上面的命令,@types/jquery這個庫就安裝到項(xiàng)目的node_modules/@types/jquery目錄,里面的index.d.ts文件就是 jQuery 的類型聲明文件。如果類型聲明文件不是index.d.ts,那么就需要在package.json的types或typings字段,指定類型聲明文件的文件名。
ts 會自動加載node_modules/@types目錄下的模塊,但可以使用編譯選項(xiàng)typeRoots改變這種行為。
{
"compilerOptions": {
"typeRoots": ["./typings", "./vendor/types"]
}
}上面示例表示,ts 不再去node_modules/@types目錄,而是去跟當(dāng)前tsconfig.json同級的typings和vendor/types子目錄,加載類型模塊了。
默認(rèn)情況下,ts會自動加載typeRoots目錄里的所有模塊,編譯選項(xiàng)types可以指定加載哪些模塊。
{
"compilerOptions": {
"types" : ["jquery"]
}
}上面設(shè)置中,types屬性是一個數(shù)組,成員是所要加載的類型模塊,要加載幾個模塊,這個數(shù)組就有幾個成員,每個類型模塊在typeRoots目錄下都有一個自己的子目錄。這樣的話,TypeScript 就會自動去jquery子目錄,加載 jQuery 的類型聲明文件。
- 找不到類型聲明文件,需要自己寫
有時實(shí)在沒有第三方庫的類型聲明文件,又很難完整給出該庫的類型描述,這時你可以告訴 ts 相關(guān)對象的類型是any。比如,使用 jQuery 的腳本可以寫成下面這樣。
declare var $:any // 或者 declare type JQuery = any; declare var $:JQuery;
上面代碼表示,jQuery 的$對象是外部引入的,類型是any,也就是 ts 不用對它進(jìn)行類型檢查。
也可以采用下面的寫法,將整個外部模塊的類型設(shè)為any。
declare module '模塊名';
有了上面的命令,指定模塊的所有接口都將視為any類型
3. declare關(guān)鍵字
類型聲明文件只包含類型描述,不包含具體實(shí)現(xiàn),所以非常適合使用declare語句來描述類型。
類型聲明文件里面,變量的類型描述必須使用declare命令,否則會報(bào)錯,因?yàn)樽兞柯暶髡Z句是值相關(guān)代碼。
declare let foo:string;
interface 類型有沒有declare都可以,因?yàn)?interface 是完全的類型代碼。
interface Foo {} // 正確
declare interface Foo {} // 正確
類型聲明文件里面,頂層可以使用export命令,也可以不用,除非使用者腳本會顯式使用export命令輸入類型。
export interface Data {
version: string;
}
4. 模塊發(fā)布
當(dāng)前模塊如果包含自己的類型聲明文件,可以在 package.json 文件里面添加一個types字段或typings字段,指明類型聲明文件的位置。
{
"name": "awesome",
"author": "Vandelay Industries",
"version": "1.0.0",
"main": "./lib/main.js",
"types": "./lib/main.d.ts"
}
如果類型聲明文件名為index.d.ts,且在項(xiàng)目的根目錄中,那就不需要在package.json里面注明了。
有時,類型聲明文件會單獨(dú)發(fā)布成一個 npm 模塊,這時就必須同時加載該模塊。
這是一個模塊的 package.json 文件,該模塊需要 browserify 模塊。由于后者的類型聲明文件是一個單獨(dú)的模塊@types/browserify,所以還需要加載那個單獨(dú)的模塊(類型聲明是個單獨(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. 三斜桿命令
如果類型聲明文件的內(nèi)容特別多,可以拆分成多個文件,然后再入口文件使用三斜桿命令去加載拆分后的文件。
舉例來說,入口文件是main.d.ts,里面的接口定義在interfaces.d.ts,函數(shù)定義在functions.d.ts。那么,main.d.ts里面可以用三斜杠命令,加載后面兩個文件。
// main.d.ts文件 /// <reference path="./interfaces.d.ts" /> /// <reference path="./functions.d.ts" />
三斜杠命令(///)是一個 ts 編譯器命令,用來指定編譯器行為。它只能用在文件的頭部,如果用在其他地方,會被當(dāng)作普通的注釋。另外,若一個文件中使用了三斜線命令,那么在三斜線命令之前只允許使用單行注釋、多行注釋和其他三斜線命令,否則三斜杠命令也會被當(dāng)作普通的注釋。
除了拆分類型聲明文件,三斜杠命令也可以用于普通腳本加載類型聲明文件。
三斜桿命令有三個參數(shù),代表不同的命令。path、types、lib
1. ///<reference path=“”>
告訴編譯器在編譯時需要包括的文件,來聲明當(dāng)前腳本依賴的類型文件。編譯器會在預(yù)處理階段,找出所有三斜杠引用的文件,將其添加到編譯列表中,然后一起編譯。
/// <reference path="./lib.ts" /> let count = add(1, 2);
上面示例表示,當(dāng)前腳本依賴于./lib.ts,里面是add()的定義。編譯當(dāng)前腳本時,還會同時編譯./lib.ts。編譯產(chǎn)物會有兩個 JS 文件,一個當(dāng)前腳本,另一個就是./lib.js。
path參數(shù)指定了所引入文件的路徑。如果該路徑是一個相對路徑,則基于當(dāng)前腳本的路徑進(jìn)行計(jì)算。
使用該命令時,有以下兩個注意事項(xiàng)。
path參數(shù)必須指向一個存在的文件,若文件不存在會報(bào)錯。path參數(shù)不允許指向當(dāng)前文件。
默認(rèn)情況下,每個三斜杠命令引入的腳本,都會編譯成單獨(dú)的 JS 文件。如果希望編譯后只產(chǎn)出一個合并文件,可以使用編譯選項(xiàng)outFile。但是,outFile編譯選項(xiàng)不支持合并 CommonJS 模塊和 ES 模塊,只有當(dāng)編譯參數(shù)module的值設(shè)為 None、System 或 AMD 時,才能編譯成一個文件。
如果打開了編譯參數(shù)noResolve,則忽略三斜杠指令。將其當(dāng)作一般的注釋,原樣保留在編譯產(chǎn)物中。
2. /// <reference types=“” />
types參數(shù)用來告訴編譯器當(dāng)前腳本依賴某個DefinitelyTyped 類型庫,通常安裝在node_modules/@types目錄。
types 參數(shù)的值是類型庫的名稱,也就是安裝到node_modules/@types目錄中的子目錄的名字。
/// <reference types="node" />
上面例子中,這個三斜杠命令表示編譯時添加 Node.js 的類型庫,實(shí)際添加的腳本是node_modules目錄里面的@types/node/index.d.ts。
可以看到,這個命令的作用類似于import命令。
注意,這個命令只在你自己手寫類型聲明文件(.d.ts文件)時,才有必要用到,也就是說,只應(yīng)該用在.d.ts文件中,普通的.ts腳本文件不需要寫這個命令。如果是普通的.ts腳本,可以使用tsconfig.json文件的types屬性指定依賴的類型庫。
3. /// <reference lib=“” />
/// <reference lib="..." />命令允許腳本文件顯式包含內(nèi)置 lib 庫,等同于在tsconfig.json文件里面使用lib屬性指定 lib 庫。
安裝 ts 軟件包時,會同時安裝一些內(nèi)置的類型聲明文件,即內(nèi)置的 lib 庫。這些庫文件位于 ts 安裝目錄的lib文件夾中,它們描述了 JavaScript 語言和引擎的標(biāo)準(zhǔn) API。
庫文件并不是固定的,會隨著 ts 版本的升級而更新。庫文件統(tǒng)一使用“lib.[description].d.ts”的命名方式,而/// <reference lib="" />里面的lib屬性的值就是庫文件名的description部分,比如lib="es2015"就表示加載庫文件lib.es2015.d.ts。
/// <reference lib="es2017.string" />
上面例子中,es2017.string對應(yīng)的庫文件就是lib.es2017.string.d.ts。
到此這篇關(guān)于TypeScript中d.ts類型聲明文件的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)TypeScript d.ts類型聲明文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
怎樣用Javascript實(shí)現(xiàn)策略模式
這篇文章主要介紹了JavaScript設(shè)計(jì)模式之策略模式,想學(xué)習(xí)設(shè)計(jì)模式的同學(xué),一定要看一下2021-04-04
BootStrap Progressbar 實(shí)現(xiàn)大文件上傳的進(jìn)度條的實(shí)例代碼
這篇文章主要介紹了BootStrap Progressbar 實(shí)現(xiàn)大文件上傳的進(jìn)度條的實(shí)例代碼的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-06-06
Textarea輸入字?jǐn)?shù)限制實(shí)例(兼容iOS&安卓)
下面小編就為大家?guī)硪黄猅extarea輸入字?jǐn)?shù)限制實(shí)例(兼容iOS&安卓)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-07-07

