一、声明空间基础:类型与变量的平行世界
1.1 两大平行空间的定义
-
类型声明空间(Type Declaration Space)
存放
type
、interface
、namespace
等类型声明 -
变量声明空间(Value Declaration Space)
存放
let
、const
、function
、class
、enum
等运行时实体
typescript
// 类型声明空间
interface User {} // ✅ 纯类型
type ID = string; // ✅ 纯类型
// 变量声明空间
let user = {}; // ✅ 变量
function getName() {} // ✅ 函数
class Product {} // ✅ 类(同时生成类型!)
1.2 空间隔离实验(关键区别)
typescript
interface Test { /* 类型空间 */ }
const Test = {}; // 变量空间 ✅ 允许同名!
type T = Test; // 指向interface
const t = Test; // 指向const变量
这种特性使得类型和实现可以同名共存,这是许多库的设计基础
二、高级空间规则:命名空间与模块的影响
2.1 命名空间的双重身份
typescript
namespace API {
export type User = {}; // 类型空间
export function getUser() {} // 变量空间
}
type U = API.User; // ✅ 类型访问
const u = API.getUser; // ✅ 函数调用
2.2 模块的声明空间隔离
typescript
// user.ts
export interface User {} // 类型空间
export const User = {}; // 变量空间 ✅ 允许
// app.ts
import { User } from './user';
type U = User; // 指向interface
const u = User; // 指向const变量
2.3 全局空间的污染与防御
typescript
// 全局类型声明(危险操作!)
declare interface Window {
myLib: any;
}
// 安全方案:使用namespace隔离
declare namespace MyGlobal {
interface Config {}
}
三、声明合并机制:空间叠加原理
3.1 interface自动合并
typescript
interface User { name: string }
interface User { age: number }
const u: User = {
name: 'Jack',
age: 30 // ✅ 合并成功
}
3.2 namespace与class合并
typescript
class Logger {}
namespace Logger {
export type Level = 'info' | 'error';
}
const level: Logger.Level = 'info'; // ✅ 类型+类合并
3.3 函数与namespace合并
typescript
function getConfig() {}
namespace getConfig {
export type Env = 'dev' | 'prod';
}
const env: getConfig.Env = 'dev'; // ✅ 函数+类型合并
四、实战场景:常见问题解决方案
4.1 类型与实现同名的最佳实践
typescript
// 正确姿势:类自动生成类型
class User {
name: string;
constructor(name: string) {
this.name = name;
}
}
// 使用时无需额外类型声明
const u: User = new User('Mike');
4.2 全局类型管理方案
typescript
// types/global.d.ts
declare namespace GlobalTypes {
interface Pagination<T> {
list: T[];
total: number;
}
}
// 业务代码中使用
function getData(): GlobalTypes.Pagination<User> { return { list: [], total: 0 };}
五、小结:声明空间的3大核心原则
- 空间隔离:类型和变量生存在平行世界,同名不冲突
- 声明合并:灵活运用interface/namespace合并机制
- 模块安全:使用namespace/module控制作用域
如果你喜欢本教程,记得点赞+收藏!关注我获取最新JavaScript/TypeScript开发干货。