01 · NOTES / WebGIS 开发
第 39 节 · 声明与模块(d.ts / declare / @types)
2026 年 9 月 1 日
第 39 节 · 声明与模块(d.ts / declare / @types)
📌 版本信息:基于 TypeScript 5.x(2026-08-29 核对) 📚 来源:TS 手册 · Declarations | 阮一峰 TS 教程 · declare | DefinitelyTyped
一、这一节的目标(模块 02 最后一节)
- 理解
.d.ts是什么:只有类型没有实现的"说明书" - 掌握
declare家族:全局变量、模块声明、环境声明 - 说清
@types/xxx生态的运作方式 - 会给一个无类型的旧 JS 库手写最小声明
- 理解
import type与编译期擦除
二、.d.ts:类型说明书
lodash.js ← 运行时实现(JS)
lodash.d.ts ← 类型说明书(没有函数体,只有签名)
// my-lib.d.ts 的样子:注意没有实现体
export interface Options { zoom: number; basemap?: string }
export function init(el: HTMLElement, opts: Options): void;
export function destroy(): void;
TS 编译时读 .d.ts 做检查,运行时加载 .js 真身——两套文件,各管一摊。你用的每个现代库(React/Leaflet/OL)都带着这套"说明书",所以编辑器才有完美补全。
三、declare 家族
// ① 全局变量声明:script 标签注入的东西(如 <script>window.APP_CONFIG</script>)
declare const APP_CONFIG: { apiUrl: string; mapKey: string };
APP_CONFIG.apiUrl; // ✅ 类型可用(运行时它真的在 window 上——声明只是告诉 TS)
// ② 全局函数(同上场景)
declare function report(msg: string): void;
// ③ 模块声明:给"没有类型的第三方库"补最小说明书
declare module 'old-leaflet-plugin' {
export function addTo(map: unknown): void;
const _default: { version: string };
export default _default;
}
// 放到项目里的 *.d.ts(如 src/globals.d.ts),TS 自动读取
// ④ 环境声明文件的组织:项目里建 src/types/globals.d.ts 收纳全局 declare
⚠️ declare 的东西必须运行时真的存在——declare const APP_CONFIG 后页面却没注入它,运行时照样 undefined。TS 不负责兑现,只负责"相信你"。
四、@types 生态
# 主流库自带类型(无需额外装):react、vue、leaflet、openlayers…
# 老库类型在 DefinitelyTyped 社区仓库(发布为 @types/xxx):
npm install -D @types/lodash
查找顺序(TS 自动解析):库自带的 types 字段 → @types/lodash 包。看 package.json 里 types/typings 字段就知道库是否自带。
有的库要关类型:// @ts-ignore(下一行豁免)→ // @ts-expect-error(更好:如果这行其实没错误会反过来报错,防止遗留)。
五、import type 与擦除
// 值导入:运行时真的加载
import { fetchQuakes } from './quake.js';
// 纯类型导入:只用于类型检查,编译后完全消失
import type { QuakeCollection } from './quake.js';
// 混合:inline type 修饰
import { fetchQuakes, type QuakeFeature } from './quake.js';
为什么用 import type:①语义清晰——它只参与编译期;②彻底避免"循环 import 运行时报 undefined"的坑(两个模块只互用对方类型时,用 import type 打破运行时环);③构建工具能放心 tree-shake。
六、动手收尾(融进 C-02b)
综合项目里会实践本节三件事:
src/types/geojson.d.ts:把 GeoJSON 的类型集中为环境声明(或直接 module 内 interface,看规模)src/types/globals.d.ts:声明演示用declare const USGS_FEED: string- 全项目
import type化:类型引用一律 type 导入
七、自测题
- .d.ts 和 .js 的分工?
declare const X: T保证 X 运行时存在吗?@types/lodash是谁维护的?库自带类型时还要装吗?@ts-expect-error比@ts-ignore好在哪?- 两个模块互相只用对方的类型时,用什么导入避免运行时循环?
参考答案
- .d.ts 只有类型签名供编译器检查;.js 是运行时实现。
- 不保证——声明只管编译期"相信你",运行时必须真的存在。
- DefinitelyTyped 社区;库自带(package.json 有 types 字段)时不用装。
- 若被标记行实际没有错误,@ts-expect-error 自己会报错——提醒你删掉过时的豁免;@ts-ignore 会永远静默。
import type——类型在编译期擦除,不产生运行时依赖边,循环环自然消失。
八、🎉 模块 02 · Web 基础 全部 39 节完结
阶段一(0127 HTML/CSS/JS/TS/Tailwind)+ 阶段二(2839 原理精通)全部产出。
收尾三件事(进入下一模块前):
- 综合项目 C-02a 个人主页:纯 HTML/CSS 响应式三页站(学完 08 就能做,现在做正好用上 Tailwind)
- 综合项目 C-02b 地震数据面板 TS 版:以
23-ts-demo的 quake.ts 为数据模块起点 + USGS 真实数据 + Tailwind 界面 - 两个项目做完在
学习计划.md打卡,然后进入 模块 03 · React 与 Next.js(章程已备好,27 节)
TAGSweb