19. 三斜线指令
19. 三斜线指令
1. 概述
三斜线指令是 TypeScript 中的特殊注释,用于在编译时引入依赖关系。它们告诉 TypeScript 编译器在编译过程中包含其他文件。虽然现代 TypeScript 项目推荐使用 ES 模块,但三斜线指令在特定场景下仍然有用。
┌─────────────────────────────────────────────────────────────┐ │ 三斜线指令系统 │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 指令类型 │ │ ├──/// <reference path="..." />:文件路径引用 ││ ├──/// <reference types="..." />:类型包引用 ││ ├──/// <reference lib="..." />:内置库引用 ││ └──/// <reference no-default-lib="true"/>:禁用默认库 ││ │ │ 适用场景 │ │ ├── 全局类型声明文件 │ │ ├── 没有模块系统的旧项目 │ │ ├── 编译时依赖管理 │ │ └── 声明文件中的依赖 │ │ │ └─────────────────────────────────────────────────────────────┘2. 三斜线指令语法
三斜线指令是单行注释,必须以三个斜杠开头。
/// <reference path="..." />/// <reference types="..." />/// <reference lib="..." />/// <reference no-default-lib="true"/>3. path 指令
path指令用于指定依赖文件路径。
3.1 基本用法
// types/global.d.tsinterfaceGlobalConfig{apiUrl:string;timeout:number;}declareconstCONFIG:GlobalConfig;// main.ts/// <reference path="./types/global.d.ts" />console.log(CONFIG.apiUrl);// TypeScript 知道 CONFIG 的类型3.2 多文件引用
// types/math.d.tsdeclarefunctionadd(a:number,b:number):number;declarefunctionmultiply(a:number,b:number):number;// types/string.d.tsdeclarefunctiontoUpperCase(str:string):string;declarefunctiontoLowerCase(str:string):string;// main.ts/// <reference path="./types/math.d.ts" />/// <reference path="./types/string.d.ts" />constsum=add(5,3);// 5constupper=toUpperCase('hello');// 'HELLO'4. types 指令
types指令用于引用 DefinitelyTyped 中的类型定义包。
/// <reference types="node" />/// <reference types="jest" />// 现在可以使用 Node.js 和 Jest 的类型importfsfrom'fs';constcontent=fs.readFileSync('file.txt','utf-8');5. lib 指令
lib指令用于显式引用内置库。
/// <reference lib="es2015" />/// <reference lib="dom" />/// <reference lib="webworker" />// 可以使用 ES2015 和 DOM 的类型constpromise=Promise.resolve(42);constelement=document.getElementById('app');6. no-default-lib 指令
no-default-lib指令用于禁用默认库。
/// <reference no-default-lib="true"/>// 这个文件不会包含默认的 lib.d.ts// 通常用于自定义运行环境7. 完整示例:全局类型系统
// ============ 1. 类型声明文件 ============// types/globals.d.ts// 全局变量声明declareconstAPP_VERSION:string;declareconstAPP_NAME:string;declareconstDEBUG:boolean;// 全局函数声明declarefunctionlog(message:string):void;declarefunctionwarn(message:string):void;declarefunctionerror(message:string):void;// 全局类声明declareclassLogger{constructor(prefix:string);log(message:string):void;setLevel(level:'debug'|'info'|'error'):void;}// 全局命名空间declarenamespaceUtils{functionformatDate(date:Date):string;functionformatNumber(num:number):string;functiongenerateId():string;}// 接口扩展declareglobal{interfaceWindow{__INITIAL_STATE__:any;__REDUX_DEVTOOLS_EXTENSION__:any;}interfaceArray<T>{last():T|undefined;first():T|undefined;}}// 导出(用于模块化)export{};// ============ 2. 实现文件 ============// src/globals.ts/// <reference path="../types/globals.d.ts" />// 实现全局变量(windowasany).APP_VERSION='1.0.0';(windowasany).APP_NAME='MyApp';(windowasany).DEBUG=process.env.NODE_ENV==='development';// 实现全局函数functionlog(message:string){console.log(`[LOG]${message}`);}functionwarn(message:string){console.warn(`[WARN]${message}`);}functionerror(message:string){console.error(`[ERROR]${message}`);}// 实现全局类classLogger{privateprefix:string;privatelevel:'debug'|'info'|'error'='info';constructor(prefix:string){this.prefix=prefix;}log(message:string){if(this.level==='debug'){console.log(`[${this.prefix}]${message}`);}}setLevel(level:'debug'|'info'|'error'){this.level=level;}}// 实现命名空间namespaceUtils{exportfunctionformatDate(date:Date):string{returndate.toISOString().split('T')[0];}exportfunctionformatNumber(num:number):string{returnnum.toLocaleString();}exportfunctiongenerateId():string{return`${Date.now()}-${Math.random().toString(36).substr(2,9)}`;}}// 实现数组扩展Array.prototype.last=function(){returnthis[this.length-1];};Array.prototype.first=function(){returnthis[0];};// ============ 3. 使用文件 ============// src/main.ts/// <reference path="../types/globals.d.ts" />// 使用全局变量console.log(`App:${APP_NAME}v${APP_VERSION}`);if(DEBUG){console.log('Debug mode enabled');}// 使用全局函数log('Application started');warn('This is a warning');error('This is an error');// 使用全局类constlogger=newLogger('MyApp');logger.log('Hello');// 使用命名空间constformattedDate=Utils.formatDate(newDate());constformattedNumber=Utils.formatNumber(1234567);constid=Utils.generateId();console.log({formattedDate,formattedNumber,id});// 使用扩展的数组方法constarr=[1,2,3];console.log(arr.first());// 1console.log(arr.last());// 3// 使用全局接口扩展window.__INITIAL_STATE__={user:'Alice'};console.log(window.__INITIAL_STATE__);8. 三斜线指令 vs 模块导入
| 特性 | 三斜线指令 | ES 模块导入 |
|---|---|---|
| 语法 | /// <reference path="..." /> | import { x } from './module' |
| 作用域 | 全局 | 模块 |
| 类型安全 | 一般 | 强 |
| 推荐程度 | 旧项目、特殊场景 | 现代项目 |
| 依赖管理 | 手动 | 自动 |
| Tree Shaking | 不支持 | 支持 |
9. 实际应用场景
9.1 声明文件中的依赖
// jquery.d.ts/// <reference types="sizzle" />declaremodule'jquery'{export=jQuery;}9.2 测试文件引用
// test/setup.ts/// <reference types="jest" />/// <reference path="../types/global.d.ts" />// 测试配置代码beforeEach(()=>{// setup});9.3 编译时配置
// tsconfig.json 配合使用{"compilerOptions":{"types":["node","jest"]}}// 或在文件中使用三斜线指令覆盖配置/// <reference lib="es2020" />10. 注意事项
| 注意事项 | 说明 |
|---|---|
| 位置限制 | 三斜线指令必须在文件顶部,只允许注释或空行在前 |
| 模块冲突 | 如果文件有 import/export,三斜线指令会被忽略 |
| 性能影响 | 过多使用会影响编译性能 |
| 推荐替代 | 新项目应使用 tsconfig.json 的 include 和 ES 模块 |
11. 总结
| 指令 | 用途 | 示例 |
|---|---|---|
path | 引用本地文件 | /// <reference path="./types.d.ts" /> |
types | 引用类型包 | /// <reference types="node" /> |
lib | 引用内置库 | /// <reference lib="es2015" /> |
no-default-lib | 禁用默认库 | /// <reference no-default-lib="true"/> |
