模块模式与泛型工厂函数结合,本质是将“封装+类型契约+按需实例化”统一于编译期可验证结构;关键在于作用域边界、类型约束、初始化路径三者严格对齐,实现高局部性安全。

模块模式与泛型工厂函数结合,本质是把“封装+类型契约+按需实例化”三者统一在编译期可验证的结构中。关键不在于堆砌设计模式,而在于让构建逻辑的**作用域边界、类型约束、初始化路径**三者严格对齐——这才是高局部性安全的核心。
明确模块边界与泛型入口点
模块应导出一个具名泛型工厂函数(非类),其类型参数带复合约束,且所有内部状态完全闭包在函数作用域内:
- 避免将泛型类暴露为模块默认导出,防止外部绕过约束直接 new 实例
- 工厂函数签名显式声明所需能力,例如:
createBuilder<t extends id: string record unknown>>()</t> - 模块内部不导出任何构造函数、类或未约束的类型别名,只暴露该工厂及配套的校验工具
用泛型约束替代运行时类型检查
局部性安全的前提是错误在调用现场即可捕获,而非延迟到构建中途或执行阶段:
- 将字段合法性、必填项、值范围等规则编码进泛型约束接口,例如定义
interface ValidatedUser extends User { readonly _validated: true } - 工厂返回类型为
Builder<validateduser></validateduser>,而非Builder<user></user>,确保下游只能接收已通过约束校验的类型 - 禁止在模块内部使用
any、unknown或类型断言绕过约束;所有中间转换必须有显式泛型映射
构建步骤链的类型流闭环
每一步构建操作都应返回新泛型实例,且类型参数随状态演进而精确收敛:
- 初始 builder 类型为
Builder<partial>></partial>,调用.withId()后变为Builder<omit>, 'id'> & { id: string }></omit> - 最终
.build()方法仅当类型参数满足完整契约(如Required<t></t>)时才可调用,否则 TS 编译报错 - 不依赖可选链或条件返回,所有分支路径都保持类型可推导;禁用
as断言强行收束类型
隔离副作用与纯构建逻辑
高局部性意味着构建器不隐式依赖外部状态、全局配置或异步资源:
- 工厂函数接受的所有参数必须是同步、确定性输入(如配置对象、默认值函数),不可含 Promise、EventEmitter 等
- 若需注入服务,通过泛型参数约束其接口(如
Service extends ILogService),并在调用时由上层传入具体实现 - 模块内部不访问 localStorage、document 或 process.env,所有环境变量需显式作为泛型约束或参数传入











