如何为TypeScript日期转换函数添加泛型类型定义
解决TypeScript日期解析函数的类型定义问题
要实现能自动关联原始JSON类型与解析后类型的日期转换函数,可以通过泛型+映射类型来解决,具体方案如下:
核心思路
通过泛型捕获原始对象的结构,结合映射类型将指定字段的类型从string(或string|null)转换为Date(或Date|null),让TypeScript自动推导输入输出的类型对应关系。
实现代码
1. 定义类型转换工具
先创建一个辅助类型,用于生成解析后的对象类型:
// 将原始类型T中的指定字段K,从字符串/字符串|null转为日期/日期|null type ParseDates<T, K extends keyof T> = Omit<T, K> & { [P in K]: T[P] extends string | null ? Date | null : Date; };
2. 为转换函数添加类型定义
修正原函数的返回值错误,并添加泛型约束:
const parseRecordDates = <T, K extends keyof T>(record: T, fields: K[]): ParseDates<T, K> => { const result = { ...record }; for (const field of fields) { if (field in record) { const value = record[field]; // 仅处理非null的字符串类型值 if (value !== null && typeof value === 'string') { result[field] = new Date(value) as ParseDates<T, K>[K]; } } } return result as ParseDates<T, K>; };
3. 使用示例
可以直接用工具类型推导解析后的类型,也可以显式定义接口:
// 原始JSON结构接口 export interface SequenceJson { rowId: string; sequenceId: number; sequenceTimestamp: string; optionalTimestamp: string | null; } // 方式1:用工具类型直接生成解析后的类型 type Sequence = ParseDates<SequenceJson, 'sequenceTimestamp' | 'optionalTimestamp'>; // 方式2:显式定义解析后的接口(和方式1效果一致) // export interface Sequence { // rowId: string; // sequenceId: number; // sequenceTimestamp: Date; // optionalTimestamp: Date | null; // } // 调用函数 const jsonData: SequenceJson = { rowId: 'ROW-001', sequenceId: 1001, sequenceTimestamp: '2024-05-20T12:00:00Z', optionalTimestamp: null }; const parsedData = parseRecordDates(jsonData, ['sequenceTimestamp', 'optionalTimestamp']); // parsedData.sequenceTimestamp 类型为Date // parsedData.optionalTimestamp 类型为Date | null
方案优势
- 类型安全:泛型
K限定为原始对象的键,避免传入不存在的字段名 - 自动推导:无需手动维护两个接口的对应关系,工具类型自动生成解析后的类型
- 运行时安全:增加了类型检查,仅处理非null的字符串值,避免无效日期转换
内容的提问来源于stack exchange,提问作者helion3
相关产品推荐
相关产品推荐

