如何为含可选字段的日志JSON创建TypeScript公共接口?
TypeScript 日志公共接口实现方案
核心接口定义
先明确必填字段的类型约束,同时支持任意可选额外字段:
// 定义日志级别枚举类型 type LogLevel = 'info' | 'warn' | 'error' | 'debug'; // 编译时约束UUID格式的字符串类型 type UUID = `${string}-${string}-${string}-${string}-${string}`; // 日志核心接口 interface LogEntry { // 必填字段 Date: string | Date; // JSON序列化时用ISO字符串,运行时可转为Date对象 logLevel: LogLevel; transactionId: UUID; details: Record<string, unknown>; // 若有固定结构可替换为自定义接口 // 允许任意额外可选字段 [key: string]: unknown; }
自定义Details结构(可选)
如果details字段有固定格式,可替换为具体接口:
interface LogDetails { message: string; errorCode?: number; stackTrace?: string; metadata?: Record<string, string>; } // 更新后的日志接口 interface LogEntry { Date: string | Date; logLevel: LogLevel; transactionId: UUID; details: LogDetails; [key: string]: unknown; }
运行时UUID校验(可选)
TypeScript的模板类型仅做编译时约束,若需运行时验证UUID有效性,可添加工具函数:
const isValidUUID = (str: string): str is UUID => { const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; return uuidRegex.test(str); }; // 使用示例 const transactionId = 'a1b2c3d4-5678-90ef-ghij-klmnopqrstuv'; if (isValidUUID(transactionId)) { const validLog: LogEntry = { Date: new Date().toISOString(), logLevel: 'error', transactionId, details: { message: '操作失败' }, service: 'payment-api' }; }
示例使用
// 符合规范的日志实例 const debugLog: LogEntry = { Date: '2024-05-20T14:30:00.000Z', logLevel: 'debug', transactionId: '98765432-10fe-dcba-9876-543210fedcba', details: { endpoint: '/api/users', method: 'GET', queryParams: { id: '123' } }, // 可选自定义字段 requestId: 'xyz-789', latencyMs: 45 };
内容的提问来源于stack exchange,提问作者Steven Ducker
相关产品推荐
相关产品推荐

