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

TypeScript如何通过匹配键名修改属性类型,将后缀At的字段转为Date类型

解决方案

1. 实现通用字段转换工具类型

利用TypeScript 4.1+支持的模板字面量类型和映射类型,构造可以自动识别At后缀字段的工具类型:

type NormalizeAtFields<T> = {
  // 遍历对象所有键,匹配后缀为At的键则替换类型为Date,否则保留原类型
  [K in keyof T]: K extends `${string}At` ? Date : T[K];
};

2. 标注函数返回值类型

给你的normalizeUser函数显式标注返回值类型,同时补充类型断言对齐运行时逻辑和TS类型推导:

type UserRaw = {
    name: string;
    createdAt: string;
};

const normalizeUser = function (attributes: UserRaw): NormalizeAtFields<UserRaw> {
    const normalized = { ...attributes };
    Object.entries(normalized).forEach(([key, value]) => {
        if (key.endsWith('At')) {
            (normalized as any)[key] = new Date(value as any);
        }
    });
    // 显式断言返回值匹配我们定义的类型
    return normalized as NormalizeAtFields<UserRaw>;
}

export type User = ReturnType<typeof normalizeUser>;
// 此时推导的User类型完全符合预期:
// {
//   name: string;
//   createdAt: Date;
// }

3. 通用版本封装(可选)

如果你需要在多个对象上复用这个转换逻辑,可以封装成泛型工具函数,所有传入的对象都会自动转换At后缀字段的类型:

function normalizeWithAtDates<T extends Record<string, any>>(raw: T): NormalizeAtFields<T> {
  const normalized = { ...raw };
  Object.entries(normalized).forEach(([key, value]) => {
    if (key.endsWith('At')) {
      (normalized as any)[key] = new Date(value as any);
    }
  });
  return normalized as NormalizeAtFields<T>;
}

// 使用示例
const normalizeUser = (raw: UserRaw) => normalizeWithAtDates(raw);
const normalizeOrder = (raw: {id: number; payAt: string}) => normalizeWithAtDates(raw);

递归处理嵌套对象(可选)

如果你的对象存在嵌套结构,也需要处理内部的At后缀字段,可以扩展工具类型为递归版本:

type NormalizeAtFieldsRecursive<T> = {
  [K in keyof T]: K extends `${string}At`
    ? Date
    : T[K] extends Record<string, any>
      ? NormalizeAtFieldsRecursive<T[K]>
      : T[K]
}

内容的提问来源于stack exchange,提问作者Martin Malinda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 02:57:05