You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现保留可空性的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;
};
*/

逻辑说明

  1. DateToNumberPrimitive:通过条件类型判断目标类型是否包含Date(包括和null/undefined的联合),如果是,则剔除其中的Date类型,替换为number;如果不是,则直接返回原类型。
  2. DateToNumber:使用映射类型遍历对象的所有属性,对每个属性应用DateToNumberPrimitive转换,同时自动保留属性的可选修饰符(?)。

内容的提问来源于stack exchange,提问作者Valentin Vignal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 00:25:58