聲明文件和內(nèi)置對(duì)象

當(dāng)使用第三方庫(kù)時(shí),我們需要引用它的聲明文件氛什,才能獲得對(duì)應(yīng)的代碼補(bǔ)全七芭、接口提示等功能。

  • declare var聲明全局變量
  • declare function聲明全局方法
  • declare class聲明全局類
  • declare enum聲明全局枚舉類型
  • declare namespace聲明(含有子屬性的)全局對(duì)象
  • interfacetype聲明全局類型
  • export導(dǎo)出變量
  • export namespace 導(dǎo)出(含有子屬性的)對(duì)象
  • export default ES6 默認(rèn)導(dǎo)出
  • export =commonjs 導(dǎo)出模塊
  • export as namespaceUMD 庫(kù)聲明全局變量
  • declare global擴(kuò)展全局變量
  • declare module擴(kuò)展模塊
  • /// <reference />三斜線指令

通常我們會(huì)把聲明語(yǔ)句放到一個(gè)單獨(dú)的文件(jQuery.d.ts)中照卦,這就是聲明文件
聲明文件必需以 .d.ts 為后綴式矫。

全局變量這種模式的聲明文件

// src/jQuery.d.ts
declare var jQuery: (selector: string) => any;

jQuery.d.ts放在項(xiàng)目目錄中,可檢查tsconfig.json 中的 files役耕、includeexclude配置采转,確保其包含了jQuery.d.ts文件

第三方聲明文件

使用 @types 統(tǒng)一管理第三方庫(kù)的聲明文件

npm install @types/jquery --save-dev

書寫聲明文件

當(dāng)一個(gè)第三方庫(kù)沒有提供聲明文件時(shí),我們就需要自己書寫聲明文件了。前面只介紹了最簡(jiǎn)單的聲明文件內(nèi)容故慈,而真正書寫一個(gè)聲明文件并不是一件簡(jiǎn)單的事板熊,以下會(huì)詳細(xì)介紹如何書寫聲明文件。

全局變量

如jQuery
declare var聲明全局變量

declare let jQuery: (selector: string) => any;
declare const jQuery: (selector: string) => any;

declare function聲明全局變量

declare function jQuery(selector: string): any;

declare class

declare class Animal {
    name: string;
    constructor(name: string);
    sayHi(): string;
}

declare enum

declare enum Directions {
    Up,
    Down,
    Left,
    Right
}

declare namespace


declare namespace jQuery {
    function ajax(url: string, settings?: any): void;
}

嵌套的命名空間

declare namespace jQuery {
    function ajax(url: string, settings?: any): void;
    namespace fn {
        function extend(object: any): void;
    }
}

interfacetype

interface AjaxSettings {
    method?: 'GET' | 'POST'
    data?: any;
}
declare namespace jQuery {
    function ajax(url: string, settings?: AjaxSettings): void;
}

為防止全局變量污染察绷,最好是放在namespace

declare namespace jQuery {
    interface AjaxSettings {
        method?: 'GET' | 'POST'
        data?: any;
    }
    function ajax(url: string, settings?: AjaxSettings): void;
}

// 使用

let settings: jQuery.AjaxSettings = {
    method: 'POST',
    data: {
        name: 'foo'
    }
};
jQuery.ajax('/api/post_something', settings);
npm包

npm 包的聲明文件可能存在于兩個(gè)地方:

  1. 與該 npm 包綁定在一起干签。判斷依據(jù)是 package.json 中有 types 字段,或者有一個(gè) index.d.ts 聲明文件拆撼。這種模式不需要額外安裝其他包容劳,是最為推薦的,所以以后我們自己創(chuàng)建 npm 包的時(shí)候闸度,最好也將聲明文件與 npm 包綁定在一起竭贩。
  2. 發(fā)布到 @types 里。我們只需要嘗試安裝一下對(duì)應(yīng)的 @types 包就知道是否存在該聲明文件筋岛,安裝命令是 npm install @types/foo --save-dev娶视。這種模式一般是由于 npm 包的維護(hù)者沒有提供聲明文件,所以只能由其他人將聲明文件發(fā)布到 @types 里了睁宰。

假如以上兩種方式都沒有找到對(duì)應(yīng)的聲明文件肪获,那么我們就需要自己為它寫聲明文件了。由于是通過 import 語(yǔ)句導(dǎo)入的模塊柒傻,所以聲明文件存放的位置也有所約束孝赫,一般有兩種方案:

  1. 創(chuàng)建一個(gè) node_modules/@types/foo/index.d.ts 文件,存放 foo 模塊的聲明文件红符。這種方式不需要額外的配置青柄,但是 node_modules 目錄不穩(wěn)定,代碼也沒有被保存到倉(cāng)庫(kù)中预侯,無(wú)法回溯版本致开,有不小心被刪除的風(fēng)險(xiǎn),故不太建議用這種方案萎馅,一般只用作臨時(shí)測(cè)試双戳。
  2. 創(chuàng)建一個(gè) types 目錄,專門用來(lái)管理自己寫的聲明文件糜芳,將 foo 的聲明文件放到 types/foo/index.d.ts 中飒货。這種方式需要配置下 tsconfig.json 中的 paths 和 baseUrl 字段。

export
npm 包的聲明文件與全局變量的聲明文件有很大區(qū)別峭竣。在 npm 包的聲明文件中塘辅,使用 declare 不再會(huì)聲明一個(gè)全局變量,而只會(huì)在當(dāng)前文件中聲明一個(gè)局部變量皆撩。只有在聲明文件中使用export導(dǎo)出扣墩,然后在使用方import導(dǎo)入后,才會(huì)應(yīng)用到這些類型聲明。

混用 declareexport

// types/foo/index.d.ts

declare const name: string;
declare function getName(): string;
declare class Animal {
    constructor(name: string);
    sayHi(): string;
}
declare enum Directions {
    Up,
    Down,
    Left,
    Right
}
interface Options {
    data: any;
}

export { name, getName, Animal, Directions, Options };

注意沮榜,與全局變量的聲明文件類似盘榨,interface 前是不需要 declare 的。

export namespace

// types/foo/index.d.ts

export namespace foo {
    const name: string;
    namespace bar {
        function baz(): string;
    }
}

// src/index.ts

import { foo } from 'foo';

console.log(foo.name);
foo.bar.baz();

export default

// types/foo/index.d.ts

export default function foo(): string;

// src/index.ts

import foo from 'foo';

foo();

注意蟆融,只有 functionclassinterface 可以直接默認(rèn)導(dǎo)出守呜,其他的變量需要先定義出來(lái)型酥,再默認(rèn)導(dǎo)出

export =
在 commonjs 規(guī)范中,我們用以下方式來(lái)導(dǎo)出一個(gè)模塊:

// types/foo/index.d.ts

export = foo;

declare function foo(): string;
declare namespace foo {
    const bar: number;
}
UMD 庫(kù)
// types/foo/index.d.ts

export as namespace foo;
export default foo;

declare function foo(): string;
declare namespace foo {
    const bar: number;
}
直接擴(kuò)展全局變量

有的第三方庫(kù)擴(kuò)展了一個(gè)全局變量查乒,可是此全局變量的類型卻沒有相應(yīng)的更新過來(lái)弥喉,就會(huì)導(dǎo)致 ts 編譯錯(cuò)誤,此時(shí)就需要擴(kuò)展全局變量的類型玛迄。比如擴(kuò)展 String 類型

interface String {
    prependHello(): string;
}

'foo'.prependHello();
在 npm 包或 UMD 庫(kù)中擴(kuò)展全局變量
// types/foo/index.d.ts

declare global {
    interface String {
        prependHello(): string;
    }
}

export {};

// src/index.ts

'bar'.prependHello();
模塊插件
// types/moment-plugin/index.d.ts

import * as moment from 'moment';

declare module 'moment' {
    export function foo(): moment.CalendarKey;
}

// src/index.ts

import * as moment from 'moment';
import 'moment-plugin';

moment.foo();
聲明文件中的依賴
// types/moment-plugin/index.d.ts

import * as moment from 'moment';

declare module 'moment' {
    export function foo(): moment.CalendarKey;
}

除了可以在聲明文件中通過 import 導(dǎo)入另一個(gè)聲明文件中的類型之外由境,還有一個(gè)語(yǔ)法也可以用來(lái)導(dǎo)入另一個(gè)聲明文件,那就是三斜線指令蓖议。

不建議使用虏杰,當(dāng)在以下幾個(gè)場(chǎng)景下,我們才需要使用三斜線指令替代 import:

  • 當(dāng)我們?cè)跁鴮懸粋€(gè)全局變量的聲明文件時(shí)
  • 當(dāng)我們需要依賴一個(gè)全局變量的聲明文件時(shí)
// types/jquery-plugin/index.d.ts

/// <reference types="jquery" />

declare function foo(options: JQuery.AjaxSettings): string;

注意勒虾,三斜線指令必須放在文件的最頂端纺阔,三斜線指令的前面只允許出現(xiàn)單行或多行注釋。

自動(dòng)生成聲明文件

如果庫(kù)的源碼本身就是由 ts 寫的修然,那么在使用 tsc 腳本將 ts 編譯為 js 的時(shí)候笛钝,添加 declaration 選項(xiàng),就可以同時(shí)也生成 .d.ts 聲明文件了愕宋。

tsc test.ts -d

發(fā)布聲明文件

此時(shí)有兩種方案:

  1. 將聲明文件和源碼放在一起
  2. 將聲明文件發(fā)布到 @types 下
    這兩種方案中優(yōu)先選擇第一種方案玻靡。保持聲明文件與源碼在一起,使用時(shí)就不需要額外增加單獨(dú)的聲明文件庫(kù)的依賴了中贝,而且也能保證聲明文件的版本與源碼的版本保持一致囤捻。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市雄妥,隨后出現(xiàn)的幾起案子最蕾,更是在濱河造成了極大的恐慌,老刑警劉巖老厌,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘟则,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡枝秤,警方通過查閱死者的電腦和手機(jī)醋拧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人丹壕,你說(shuō)我怎么就攤上這事庆械。” “怎么了菌赖?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵缭乘,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我琉用,道長(zhǎng)堕绩,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任邑时,我火速辦了婚禮奴紧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘晶丘。我一直安慰自己黍氮,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布浅浮。 她就那樣靜靜地躺著沫浆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脑题。 梳的紋絲不亂的頭發(fā)上件缸,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音叔遂,去河邊找鬼他炊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛已艰,可吹牛的內(nèi)容都是我干的痊末。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼哩掺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼凿叠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起嚼吞,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤盒件,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后舱禽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炒刁,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年誊稚,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了翔始。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片罗心。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖城瞎,靈堂內(nèi)的尸體忽然破棺而出渤闷,到底是詐尸還是另有隱情,我是刑警寧澤脖镀,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布飒箭,位于F島的核電站,受9級(jí)特大地震影響蜒灰,放射性物質(zhì)發(fā)生泄漏补憾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一卷员、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧腾务,春花似錦毕骡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至启昧,卻和暖如春叙凡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背密末。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工握爷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人严里。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓新啼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親刹碾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子燥撞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 本文摘自 https://ts.xcatliu.com/basics/declaration-files 聲明文件...
    Lia代碼豬崽閱讀 902評(píng)論 0 1
  • 引至: https://ts.xcatliu.com/basics/declaration-files decla...
    shuaiutopia閱讀 773評(píng)論 0 1
  • 點(diǎn)擊原文 now我們來(lái)看一看TS怎么聲明文件, 在JS里面我們經(jīng)常會(huì)使用各種第三方類庫(kù)迷帜,引入方式也不太相同物舒,常見的...
    videring閱讀 3,122評(píng)論 0 4
  • 當(dāng)使用第三方庫(kù)時(shí),我們需要引用它的聲明文件戏锹,才能獲得對(duì)應(yīng)的代碼補(bǔ)全冠胯、接口提示等功能。這是因?yàn)榍岸说谌綆?kù)大多都是非...
    CondorHero閱讀 4,893評(píng)論 1 5
  • 簡(jiǎn)介 聲明文件是以.d.ts為后綴的文件景用,開發(fā)者在聲明文件中編寫類型聲明涵叮,TypeScript根據(jù)聲明文件的內(nèi)容進(jìn)...
    刷題刷到手抽筋閱讀 4,152評(píng)論 0 1