TypeScript中declare關(guān)鍵字的具體使用
1. 簡(jiǎn)介
declare關(guān)鍵字用來告訴編譯器,某個(gè)類型是存在的,可以在當(dāng)前文件中使用。
作用:就是讓當(dāng)前文件可以使用其他文件聲明的類型。比如,自己的腳本使用外部庫定義的函數(shù),編譯器會(huì)因?yàn)椴恢劳獠亢瘮?shù)的類型定義而報(bào)錯(cuò),這時(shí)就可以在自己的腳本里面使用declare關(guān)鍵字,告訴編譯器外部函數(shù)的類型,這樣編譯腳本就不會(huì)因?yàn)槭褂昧送獠款愋投鴪?bào)錯(cuò)。
declare關(guān)鍵字可以描述變量、type或者interface命令聲明的類型、class、Enum、函數(shù)、模塊和命名空間。
declare關(guān)鍵字最重要的特點(diǎn)是,它只是通知編譯器某個(gè)類型是存在的,不用給出具體實(shí)現(xiàn)。比如只描述函數(shù)的類型,不給出函數(shù)的實(shí)現(xiàn),如果不使用declare,是做不到的。
declare只能用來描述已經(jīng)存在的變量和數(shù)據(jù)結(jié)構(gòu),不能用來聲明新的變量和數(shù)據(jù)結(jié)構(gòu)。另外所有declare語句都不會(huì)出現(xiàn)在編譯后的文件里面。
2. declare variable
可以給出外部變量的類型描述。比如當(dāng)前腳本使用了其他腳本定義的全局變量x,因?yàn)楫?dāng)前腳本不知道它的類型,編譯器會(huì)報(bào)錯(cuò),而此時(shí)要是使用declare命令給出它的類型,就不會(huì)報(bào)錯(cuò)。
x = 123; // 報(bào)錯(cuò) declare let x:number; x = 1;
如果declare關(guān)鍵字沒有給出變量的具體類型,則變量類型為any。
如果ts沒有找到declare關(guān)鍵字給出的變量,則假定它的類型為any。
declare 關(guān)鍵字只用來給出類型描述,是純的類型代碼,不允許設(shè)置變量的初始值,不涉及到值,否則會(huì)報(bào)錯(cuò)。
// 報(bào)錯(cuò) declare let x:number = 1;
3. declare function
declare關(guān)鍵字可以給出外部函數(shù)的類型。
declare function sayHello( name:string ):void; sayHello('張三');
在ts中不能單獨(dú)的聲明函數(shù)類型
// 報(bào)錯(cuò) function sayHello( name:string ):void; function sayHello(name) { return '你好,' + name; }
4. declare class
declare可以給出class類型的描述
declare class Animal { constructor(name:string); eat():void; sleep():void; }
5. declare module、declare namespace
如果想把變量、函數(shù)、類組織在一起,可以將declare與module或namespace一起使用。
declare namespace AnimalLib { class Animal { constructor(name:string); eat():void; sleep():void; } type Animals = 'Fish' | 'Dog'; } // 或者 declare module AnimalLib { class Animal { constructor(name:string); eat(): void; sleep(): void; } type Animals = 'Fish' | 'Dog'; }
declare module 和 declare namespace 里面,加不加 export 關(guān)鍵字都可以。
declare namespace Foo { export var a: boolean; } declare module 'io' { export function readFile(filename:string):string; }
例子:使用外部庫(myLib)
declare namespace myLib { function makeGreeting(s:string): string; let numberOfGreetings: number; }
可以為外部模塊添加屬性和方法時(shí),給出新增部分的類型描述。
這里從模塊moduleA
導(dǎo)入了Foo
接口,將其重命名為Bar
,并用 declare 關(guān)鍵字為Bar
增加一個(gè)屬性custom
import { Foo as Bar } from 'moduleA'; declare module 'moduleA' { interface Bar extends Foo { custom: { prop1: string; } } }
例子:一個(gè)項(xiàng)目有多個(gè)模塊,可以在一個(gè)模塊中,對(duì)另一個(gè)模塊的接口進(jìn)行類型擴(kuò)展。
這里腳本a.ts
定義了一個(gè)接口A
,腳本b.ts
為這個(gè)接口添加了屬性y
。declare module './a' {}
表示對(duì)a.ts
里面的模塊,進(jìn)行類型聲明,而同名 interface 會(huì)自動(dòng)合并,所以等同于擴(kuò)展類型。實(shí)質(zhì)是新增了一個(gè)同名的接口,因?yàn)槭峭麜?huì)自動(dòng)合并。
// a.ts export interface A { x: number; } // b.ts import { A } from './a'; declare module './a' { interface A { y: number; } } const a:A = { x: 0, y: 0 };
使用這種語法進(jìn)行模塊的類型擴(kuò)展時(shí),有兩點(diǎn)需要注意:
(1)declare module NAME
語法里面的模塊名NAME
,跟 import 和 export 的模塊名規(guī)則是一樣的,且必須跟當(dāng)前文件加載該模塊的語句寫法(上例import { A } from './a'
)保持一致。
(2)不能創(chuàng)建新的頂層類型。也就是說,只能對(duì)a.ts
模塊中已經(jīng)存在的類型進(jìn)行擴(kuò)展,不允許增加新的頂層類型,比如新定義一個(gè)接口B
。
(3)不能對(duì)默認(rèn)的default
接口進(jìn)行擴(kuò)展,只能對(duì) export 命令輸出的命名接口進(jìn)行擴(kuò)充。這是因?yàn)樵谶M(jìn)行類型擴(kuò)展時(shí),需要依賴輸出的接口名。
對(duì)于某些第三方模塊,原始作者沒有提供接口類型,這時(shí)可以在自己的腳本頂部加上下面一行命令。加上上面的命令以后,外部模塊即使沒有類型聲明,也可以通過編譯。但是,從該模塊輸入的所有接口都將為any
類型。
declare module "模塊名"; // 例子 declare module "hot-new-module";
declare module 描述的模塊名可以使用通配符。模塊名my-plugin-*
表示適配所有以my-plugin-
開頭的模塊名(比如my-plugin-logger
)。
declare module 'my-plugin-*' { interface PluginOptions { enabled: boolean; priority: number; } function initialize(options: PluginOptions): void; export = initialize; }
6. declare global
如果要為js的原生對(duì)象添加屬性和方法,可以使用declare global{}語法。只能擴(kuò)充現(xiàn)有對(duì)象的類型描述,不能增加新的頂層類型。
這里為js原生的String
對(duì)象添加了toSmallString()
方法并給出這個(gè)新增方法的類型描述。
其中第一行的空導(dǎo)出語句export {}
,作用是強(qiáng)制編譯器將這個(gè)腳本當(dāng)作模塊處理。這是因?yàn)?code>declare global必須用在模塊里面。
export {}; declare global { interface String { toSmallString(): string; } } String.prototype.toSmallString = ():string => { // 具體實(shí)現(xiàn) return ''; };
7. declare enum
可以給出Enum類型描述
declare enum E1 { A, B, } declare enum E2 { A = 0, B = 1, } declare const enum E3 { A, B, } declare const enum E4 { A = 0, B = 1, }
8. declare module 用于類型聲明文件
可以為每個(gè)模塊腳本,定義一個(gè).d.ts
文件,把該腳本用到的類型定義都放在這個(gè)文件里面。但是,更方便的做法是為整個(gè)項(xiàng)目,定義一個(gè)大的.d.ts
文件,在這個(gè)文件里面使用declare module
定義每個(gè)模塊腳本的類型。
定義
這里url和path都是單獨(dú)的模塊腳本,它們的類型都定義在node.d.ts這個(gè)文件中。
// node.d.ts declare module "url" { export interface Url { protocol?: string; hostname?: string; pathname?: string; } export function parse( urlStr: string, parseQueryString?, slashesDenoteHost? ): Url; } declare module "path" { export function normalize(p: string): string; export function join(...paths: any[]): string; export var sep: string; }
使用
使用時(shí),自己的腳本使用三斜杠命令,加載這個(gè)類型聲明文件。
/// <reference path="node.d.ts"/>
到此這篇關(guān)于TypeScript中declare關(guān)鍵字的具體使用的文章就介紹到這了,更多相關(guān)TypeScript declare關(guān)鍵字內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序canvas.drawImage完全顯示圖片問題的解決
這篇文章主要介紹了微信小程序canvas.drawImage完全顯示圖片問題的解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11