命名空间
namespaces、augmentation、global augmentation。
25 分钟
命名空间
在 ES Module 成为主流之前,TypeScript namespace 用于组织代码与避免全局污染。现代项目优先 import/export,但读懂遗留库、做 模块增强(module augmentation) 与 全局类型扩展 仍需 namespace 知识。本课补充 typescript-essentials 模块课未覆盖的内容,并说明与 nestjs-essentials、nextjs-essentials 第三方类型声明的关系。
学习目标
- 理解 namespace vs ES Module 的取舍
- 使用
declare module增强第三方库类型 - 编写 global augmentation 扩展全局类型
基本 namespace
namespace Validation {
export interface StringValidator {
isValid(s: string): boolean;
}
export class EmailValidator implements StringValidator {
isValid(s: string): boolean {
return s.includes("@");
}
}
}
const validator = new Validation.EmailValidator();
嵌套与合并
namespace App {
export namespace Models {
export interface User {
id: number;
name: string;
}
}
}
// namespace 可声明合并
namespace App.Models {
export interface User {
email?: string;
}
}
const user: App.Models.User = { id: 1, name: "Lee" };
模块增强 Module Augmentation
// types/express.d.ts
import "express";
declare module "express-serve-static-core" {
interface Request {
userId?: number;
}
}
// 之后在 middleware 中
// req.userId 有类型提示
全局增强 Global Augmentation
// types/global.d.ts
export {};
declare global {
interface Window {
__APP_CONFIG__?: {
apiBase: string;
};
}
namespace NodeJS {
interface ProcessEnv {
DATABASE_URL: string;
NODE_ENV: "development" | "production" | "test";
}
}
}
namespace 与模块互操作
// 不推荐新代码使用,但阅读 .d.ts 时会遇到
export namespace Utils {
export function formatDate(d: Date): string {
return d.toISOString();
}
}
// 现代写法
export function formatDate(d: Date): string {
return d.toISOString();
}
练习
- 为 Express
Request增加 字段的类型增强