当前位置: 首页 > news >正文

14. 声明文件(Declaration Files)

14. 声明文件(Declaration Files)

1. 概述

声明文件(.d.ts文件)用于描述 JavaScript 库的类型信息,让 TypeScript 能够理解和使用纯 JavaScript 编写的代码。声明文件只包含类型定义,不包含实现代码。

┌─────────────────────────────────────────────────────────────┐ │ 声明文件系统 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 声明文件的作用 │ │ ├── 为 JavaScript 库提供类型信息 │ │ ├── 让 TypeScript 理解全局变量 │ │ ├── 扩展现有模块的类型 │ │ └── 为项目提供统一的类型定义 │ │ │ │ 声明文件来源 │ │ ├── 内置类型:TypeScript 自带(lib.d.ts) │ │ ├── DefinitelyTyped:`@types/*`包 │ │ ├── 库自带:库内置类型定义 │ │ └── 自定义:项目内手写声明 │ │ │ │ 声明语法 │ │ ├──declarevar:声明全局变量 │ │ ├──declarefunction:声明函数 │ │ ├──declareclass:声明类 │ │ ├──declaremodule:声明模块 │ │ ├──declarenamespace:声明命名空间 │ │ └──declareglobal:扩展全局类型 │ │ │ └─────────────────────────────────────────────────────────────┘

2. 为什么需要声明文件

2.1 没有声明文件的问题

// utils.js(纯 JavaScript)exportfunctionformatPrice(price,currency='¥'){return`${currency}${price.toFixed(2)}`;}exportconstAPI_URL='https://api.example.com';exportclassUser{constructor(name){this.name=name;}greet(){return`Hello,${this.name}`;}}
// app.ts(TypeScript)import{formatPrice,API_URL,User}from'./utils.js';// TypeScript 无法推断类型,所有导入都是 any 类型constprice=formatPrice(99.9);// anyconsturl=API_URL;// anyconstuser=newUser('Alice');// any

2.2 添加声明文件

// utils.d.tsdeclaremodule'./utils.js'{exportfunctionformatPrice(price:number,currency?:string):string;exportconstAPI_URL:string;exportclassUser{constructor(name:string);name:string;greet():string;}}

3. 声明语法

3.1 declare var / let / const

// global.d.ts// 声明全局变量declarevar__VERSION__:string;declarelet__DEBUG__:boolean;declareconst__API_URL__:string;// 声明全局函数declarefunctionlog(message:string):void;// 声明全局类declareclassGlobalService{staticinstance:GlobalService;getName():string;}

3.2 declare function

// 声明函数重载declarefunctioncreateElement(tag:string):HTMLElement;declarefunctioncreateElement(tag:string,props:object):HTMLElement;declarefunctioncreateElement(tag:string,props:object,...children:any[]):HTMLElement;// 声明函数属性declarefunctionfetch(url:string):Promise<Response>;declarenamespacefetch{functionpolyfill():void;constisSupported:boolean;}

3.3 declare class

// 声明类declareclassAnimal{constructor(name:string);name:string;speak():void;staticcreate(name:string):Animal;}// 声明抽象类declareabstractclassShape{abstractgetArea():number;getPerimeter():number;}

3.4 declare module

// 声明外部模块declaremodule'lodash'{exportfunctionchunk<T>(array:T[],size:number):T[][];exportfunctiondebounce<Textends(...args:any[])=>any>(func:T,wait:number):T;}// 声明模块通配符declaremodule'*.css'{constcontent:{[className:string]:string};exportdefaultcontent;}declaremodule'*.vue'{importtype{DefineComponent}from'vue';constcomponent:DefineComponent<{},{},any>;exportdefaultcomponent;}declaremodule'*.png'{constsrc:string;exportdefaultsrc;}

3.5 declare namespace

// 声明命名空间declarenamespaceMyLib{functiondoSomething():void;namespaceUtils{functionhelper():string;}interfaceOptions{debug:boolean;timeout:number;}}// 使用MyLib.doSomething();MyLib.Utils.helper();

3.6 declare global

// 扩展全局类型declareglobal{interfaceWindow{myCustomProperty:string;myAPI:{getData():Promise<any>;};}interfaceArray<T>{last():T|undefined;first():T|undefined;}}// 使用window.myCustomProperty='value';constlast=[1,2,3].last();// 3

4. DefinitelyTyped

4.1 安装类型定义

# 安装 Node.js 类型npminstall--save-dev @types/node# 安装 React 类型npminstall--save-dev @types/react# 安装 Lodash 类型npminstall--save-dev @types/lodash# 安装 Express 类型npminstall--save-dev @types/express

4.2 使用示例

// 安装后自动可用,无需额外配置import*asexpressfrom'express';import*as_from'lodash';constapp=express();// 类型正确constchunked=_.chunk([1,2,3,4],2);// number[][]

5. 编写声明文件

5.1 为 JavaScript 库编写声明

// my-library.d.ts// 假设有一个 JavaScript 库 my-library// 模块声明declaremodule'my-library'{// 配置接口exportinterfaceConfig{debug?:boolean;timeout?:number;retries?:number;}// 主要函数exportfunctioninit(config:Config):void;exportfunctiongetData<T>(url:string):Promise<T>;exportfunctionpostData<T>(url:string,data:any):Promise<T>;// 类exportclassClient{constructor(config:Config);request<T>(url:string):Promise<T>;close():void;}// 常量exportconstversion:string;exportconstAPI_BASE:string;}

5.2 为全局库编写声明

// global-lib.d.ts// 假设有一个全局 JavaScript 库interfaceGlobalLibConfig{mode:'development'|'production';apiUrl:string;}interfaceGlobalLibAPI{start():void;stop():void;getConfig():GlobalLibConfig;}// 声明全局变量declarevarGlobalLib:GlobalLibAPI;declarefunctioninitGlobalLib(config:GlobalLibConfig):void;

5.3 扩展现有模块

// express-extensions.d.tsimport'express';declaremodule'express'{interfaceRequest{user?:{id:number;name:string;role:'admin'|'user';};startTime:number;}interfaceResponse{success<T>(data:T):this;error(message:string,code?:number):this;}}

6. 声明文件的类型导出

6.1 导出类型

// types/index.d.tsexportinterfaceUser{id:number;name:string;email:string;}exporttypeUserRole='admin'|'user'|'guest';exportconstdefaultUser:User;exportfunctioncreateUser(name:string,email:string):User;

6.2 默认导出

// logger.d.tsdeclareclassLogger{constructor(name:string);info(message:string):void;error(message:string):void;warn(message:string):void;}exportdefaultLogger;

6.3 混合导出

// utils.d.tsexportconstversion:string;exportfunctionformatDate(date:Date):string;exportfunctionformatNumber(num:number):string;exportdefault{version,formatDate,formatNumber};

7. 完整示例:为 API 客户端编写声明

// api-client.js(假设是已有的 JavaScript 代码)// ============ 1. 声明文件 ============// api-client.d.tsdeclaremodule'api-client'{// 请求配置exportinterfaceRequestConfig{method?:'GET'|'POST'|'PUT'|'DELETE';headers?:Record<string,string>;timeout?:number;retries?:number;}// 响应类型exportinterfaceApiResponse<T=any>{success:boolean;data:T;message:string;code:number;timestamp:number;}// 错误类型exportinterfaceApiError{code:number;message:string;details?:any;}// 拦截器exportinterfaceInterceptor{request?:(config:RequestConfig)=>RequestConfig;response?:<T>(response:ApiResponse<T>)=>ApiResponse<T>;error?:(error:ApiError)=>void;}// 客户端类exportclassApiClient{constructor(baseURL:string,config?:RequestConfig);get<T>(url:string,config?:RequestConfig):Promise<ApiResponse<T>>;post<T>(url:string,data?:any,config?:RequestConfig):Promise<ApiResponse<T>>;put<T>(url:string,data?:any,config?:RequestConfig):Promise<ApiResponse<T>>;delete<T>(url:string,config?:RequestConfig):Promise<ApiResponse<T>>;addInterceptor(interceptor:Interceptor):void;removeInterceptor(interceptor:Interceptor):void;setToken(token:string):void;clearToken():void;}// 工厂函数exportfunctioncreateClient(baseURL:string,config?:RequestConfig):ApiClient;// 默认导出exportdefaultApiClient;}// ============ 2. 使用示例 ============// app.tsimportApiClient,{createClient,ApiResponse}from'api-client';interfaceUser{id:number;name:string;email:string;}// 方式1:使用类constclient=newApiClient('https://api.example.com',{timeout:5000,retries:3});client.setToken('your-token');constresponse=awaitclient.get<User[]>('/users');if(response.success){console.log(response.data);// User[]}// 方式2:使用工厂函数constclient2=createClient('https://api.example.com');// 添加拦截器client2.addInterceptor({request:(config)=>{console.log('Request:',config);returnconfig;},response:(res)=>{console.log('Response:',res);returnres;}});

8. 发布类型定义

8.1 package.json 配置

{"name":"my-library","version":"1.0.0","main":"dist/index.js","types":"dist/index.d.ts","files":["dist/**/*.js","dist/**/*.d.ts"],"scripts":{"build":"tsc","prepublishOnly":"npm run build"}}

8.2 双包发布

{"name":"my-library","version":"1.0.0","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"import":"./dist/index.mjs","require":"./dist/index.js","types":"./dist/index.d.ts"},"./utils":{"import":"./dist/utils.mjs","require":"./dist/utils.js","types":"./dist/utils.d.ts"}}}

9. 常见模式

9.1 条件类型导出

declaremodule'my-utils'{exportfunctionisString(value:unknown):valueisstring;exportfunctionisNumber(value:unknown):valueisnumber;exportfunctionisArray<T>(value:unknown):valueisT[];}

9.2 泛型类型导出

declaremodule'my-utils'{exportfunctionmap<T,U>(array:T[],fn:(item:T,index:number)=>U):U[];exportfunctionfilter<T>(array:T[],predicate:(item:T)=>boolean):T[];exportfunctionreduce<T,U>(array:T[],reducer:(acc:U,item:T)=>U,initialValue:U):U;}

9.3 可调用接口

declaremodule'my-utils'{interfaceMyFunction{(value:string):number;version:string;config:{debug:boolean};}constmyFunction:MyFunction;exportdefaultmyFunction;}

10. 总结

声明类型语法用途
变量declare var name: type声明全局变量
函数declare function name(params): return声明全局函数
declare class Name { ... }声明全局类
模块declare module 'name' { ... }声明外部模块
命名空间declare namespace Name { ... }声明命名空间
全局扩展declare global { ... }扩展全局类型
通配符declare module '*.ext'声明文件模块

http://www.jsqmd.com/news/861262/

相关文章:

  • 创业公司如何做好用户反馈管理
  • 紧急通知:Claude文档解析API响应延迟突增300%?立即启用这3个异步缓存+增量摘要策略保生产可用性
  • Claude Code配置国产模型
  • 微信聊天记录永久保存指南:5分钟掌握WeChatMsg完整备份方案
  • ElevenLabs波斯文TTS落地难题全破解:从Unicode乱码、音节切分失败到自然语调合成的5大技术卡点
  • 拒绝C盘爆红!自制 Windows 系统垃圾一键清理工具(精美UI设计)
  • Python数据流式处理:Streaming深度解析与实战
  • 谷歌搜索SEO优化需要做什么?4个步骤快速做好站内优化
  • Claude Code 6 种权限模式对照表
  • ElevenLabs方言语音开发指南(山东话专项版):从API密钥配置到“俺、恁、咋呼”等27个地域性语义单元精准建模
  • LLM 认知框架:揭秘时间序列与空间结构,洞悉 AI 未来!
  • 谷歌搜索SEO优化需要做什么?解决未建立索引的2个技术点
  • ElevenLabs支持闽南语吗?福建话语音合成实测:从API调用到音色克隆的7步通关手册
  • 15. tsconfig.json 配置详解
  • 单智能体 vs 多智能体系统:架构对比与选择
  • UVa 12572 RMQ Overkill
  • 自指系统与算术障碍的跨领域猜想:封闭认知框架下的几何-物理-计算统一理论研究(世毫九实验室原创研究)
  • Token销毁机制深度解析:从原理到实战,开发者必读指南
  • 【仅限西北开发者内部流通】ElevenLabs陕西话语音微调秘钥+定制音色包(含西安/榆林/延安三地口音模型)
  • Rust分布式系统最佳实践:构建高可用、高性能的后端服务
  • 【编号884】江西省各城市-春节人口迁徙规模数据(2019-2025)
  • 福建话TTS落地难?手把手教你绕过ElevenLabs官方未公开的闽东方言/莆仙话语音注入方案,限时可复现
  • 嵌入式测试学习第 16 天:复位电路、电源电路基础原理
  • UVa 250 Pattern Matching Prelims
  • 【编号938】东南沿海诸河流域边界+东南沿海诸河流域水系矢量多级水系
  • 边缘AI框架:在边缘设备上运行AI模型
  • cursor-vip:当AI编程工具遇上共享经济,你的代码从此有了智能伙伴
  • 16. 编译与构建工具
  • 2026电镀镍标牌技术全解析:镍标牌厂家/镍标牌定制/镍转印标/不锈钢标牌/家电标牌/枪瞄标牌/电动车标牌/电铸镍标牌/选择指南 - 优质品牌商家
  • Python微服务架构:从单体到分布式的演进