如何实现保留可空性的DateToNumber类型转换?
实现正确的
DateToNumber类型 要解决这个问题,我们需要精准识别对象中Date类型的属性(包括可空、可选的Date),将其转换为number,同时完全保留非Date属性的原有类型(包括可空性、可选性)。
错误实现的问题分析
常见的错误实现通常会直接对所有属性做宽泛的联合类型替换,比如:
// 错误示例 type BadDateToNumber<T> = { [K in keyof T]: T[K] extends Date ? number : T[K] | number; };
这种写法会把非Date的可空属性也混入number类型,同时无法正确保留可选属性的修饰符。
正确的类型实现
我们可以分两步实现:首先处理单个值的转换逻辑,再用映射类型遍历对象属性并保留可选性:
// 处理单个值的转换:仅把Date(包括和null/undefined的联合)转为number,其他类型原样保留 type DateToNumberPrimitive<T> = T extends Date | null | undefined ? Exclude<T, Date> | number : T; // 遍历对象属性,保留可选修饰符,应用上面的转换逻辑 type DateToNumber<T> = { [K in keyof T]: DateToNumberPrimitive<T[K]>; };
测试验证
用几个测试用例验证效果:
// 原类型 type OriginalType = { createdAt: Date; updatedAt: Date | null; name: string | undefined; age?: number; optionalDate?: Date | undefined; }; // 转换后的类型 type ConvertedType = DateToNumber<OriginalType>; /* 转换结果符合预期: type ConvertedType = { createdAt: number; updatedAt: number | null; name: string | undefined; age?: number | undefined; optionalDate?: number | undefined; }; */
逻辑说明
DateToNumberPrimitive:通过条件类型判断目标类型是否包含Date(包括和null/undefined的联合),如果是,则剔除其中的Date类型,替换为number;如果不是,则直接返回原类型。DateToNumber:使用映射类型遍历对象的所有属性,对每个属性应用DateToNumberPrimitive转换,同时自动保留属性的可选修饰符(?)。
内容的提问来源于stack exchange,提问作者Valentin Vignal
相关产品推荐
相关产品推荐

