类型安全模板生成器设计:无状态多模板文档生成服务方案咨询
无状态多模板文档生成服务解决方案
核心设计方案
采用策略模式结合TypeScript泛型实现:将各模板的生成逻辑封装为独立无状态策略类,通过统一入口类关联模板枚举与对应策略,同时利用TS条件类型实现参数自动推断,兼顾扩展性与类型安全性。
详细实现步骤
1. 定义基础类型与枚举
先明确模板标识、各模板专属数据结构,以及模板与数据的映射关系:
// 模板枚举 enum TemplateEnum { Invoice = 'invoice', Report = 'report' } // 发票模板数据结构 interface InvoiceData { customerName: string; amount: number; items: Array<{ name: string; price: number; quantity: number }>; } // 报告模板数据结构 interface ReportData { title: string; author: string; content: string; } // 模板-数据类型映射表,用于TS自动推断 type TemplateDataMap = { [TemplateEnum.Invoice]: InvoiceData; [TemplateEnum.Report]: ReportData; }; // 所有模板生成器必须实现的统一接口 interface TemplateGenerator<T> { generate(data: T): Buffer; }
2. 实现各模板生成策略
每个模板对应独立的无状态生成器类,专注自身文档生成逻辑:
// 发票生成器 class InvoiceGenerator implements TemplateGenerator<InvoiceData> { generate(data: InvoiceData): Buffer { // 此处替换为真实生成逻辑(如pdf-lib、puppeteer生成PDF Buffer) const invoiceContent = `Invoice\nCustomer: ${data.customerName}\nTotal: $${data.amount}`; return Buffer.from(invoiceContent); } } // 报告生成器 class ReportGenerator implements TemplateGenerator<ReportData> { generate(data: ReportData): Buffer { // 此处替换为真实生成逻辑 const reportContent = `Report: ${data.title}\nAuthor: ${data.author}\nContent: ${data.content}`; return Buffer.from(reportContent); } }
3. 实现统一入口类DocumentGenerator
通过静态方法封装模板与生成器的映射,提供类型安全的调用入口:
class DocumentGenerator { // 静态映射表:模板枚举 -> 对应生成器实例(无状态,可复用) private static readonly generatorMap: Record<TemplateEnum, TemplateGenerator<any>> = { [TemplateEnum.Invoice]: new InvoiceGenerator(), [TemplateEnum.Report]: new ReportGenerator() }; // 泛型create方法,自动匹配模板对应的数据类型 static create<T extends TemplateEnum>( template: T, data: TemplateDataMap[T] ): Buffer { const generator = this.generatorMap[template]; if (!generator) { throw new Error(`Unsupported template: ${template}`); } return generator.generate(data); } }
4. 使用示例
完全符合预期调用方式,且TS会自动校验数据类型合法性:
const invoiceData: InvoiceData = { customerName: 'John Doe', amount: 150, items: [{ name: 'Item A', price: 50, quantity: 3 }] }; const reportData: ReportData = { title: 'Annual Report', author: 'Jane Smith', content: 'This is the content of the report.' }; // 自动校验reportData必须符合ReportData类型,返回报告Buffer const reportBuffer = DocumentGenerator.create(TemplateEnum.Report, reportData); // 自动校验invoiceData必须符合InvoiceData类型,返回发票Buffer const invoiceBuffer = DocumentGenerator.create(TemplateEnum.Invoice, invoiceData);
扩展性说明
- 新增模板只需五步:
- 在
TemplateEnum中添加新标识 - 定义对应的数据结构(如
ContractData) - 更新
TemplateDataMap关联新模板与数据类型 - 实现新的生成器类(如
ContractGenerator)并实现TemplateGenerator接口 - 在
DocumentGenerator.generatorMap中添加新映射
- 在
- 所有生成器均为无状态设计,可安全复用实例,无状态污染风险
- TypeScript编译期校验可提前拦截参数不匹配问题,降低运行时错误
内容的提问来源于stack exchange,提问作者cuaies
相关产品推荐
相关产品推荐

