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

TypeScript中type/interface如何设置字段键别名映射数据库短键到全名字段

TS 本身没有提供直接在类型定义里声明字段别名的语法,你可以通过「统一维护映射字典 + 自动推导类型 + 通用转换逻辑」的方案实现全链路自动化,完全不需要手写两套类型和逐个字段赋值的转换函数。

方案1:类型安全的映射转换(推荐)

只需要维护1份短键和长键的对应关系,类型和转换逻辑自动同步,避免漏改、错改问题:

// 唯一需要手动维护的映射字典:短键名 => 应用层长键名
export const LOG_FIELD_MAP = {
  _id: 'messageId',
  date: 'date',
  uid: 'userId',
  l: 'login',
  dn: 'displayName',
  m: 'message',
  c: 'color',
  b: 'badges',
  bi: 'badgeInfo',
  e: 'emotes',
  si: 'subInfo',
  d: 'duration',
  j: 'joined',
  p: 'parted',
  mt: 'messageType'
} as const;

// 手动维护字段值类型,修改字段时只需要改这里
type LogFieldValueTypes = {
  _id: string;
  date: string;
  uid: number;
  l: string;
  dn: string;
  m: string;
  c: string;
  b: Badges;
  bi: BadgeInfo;
  e: RawEmotes;
  si: SubInfo;
  d: number;
  j: string[];
  p: string[];
  mt: MessageType;
};

// 自动生成原始数据库返回的Log类型,不需要手动写
export type Log = { [K in keyof LogFieldValueTypes]: LogFieldValueTypes[K] };

// 自动生成应用层用的LogAlias类型,不需要手动写
export type LogAlias = {
  [K in keyof typeof LOG_FIELD_MAP as typeof LOG_FIELD_MAP[K]]: 
    K extends keyof LogFieldValueTypes ? LogFieldValueTypes[K] : never
} & {
  // 单独处理需要二次转换的subInfo字段
  subInfo: SubInfoAlias
};

// 通用转换函数,不需要逐个字段赋值
export function convertLog(raw: Log): LogAlias {
  const res = {} as LogAlias;
  (Object.keys(LOG_FIELD_MAP) as Array<keyof typeof LOG_FIELD_MAP>).forEach(shortKey => {
    const longKey = LOG_FIELD_MAP[shortKey];
    // 特殊处理需要单独转换的字段
    if (shortKey === 'si') {
      res.subInfo = convertSubInfo(raw.si);
      return;
    }
    res[longKey] = raw[shortKey] as any;
  });
  return res;
}

方案2:Proxy零拷贝代理(适合数据量极大的场景)

如果你的Log数据量特别大,不想额外复制一份对象占用内存,可以用Proxy做运行时的键名代理,不需要修改原始对象:

export function createLogProxy(raw: Log): LogAlias {
  const reverseMap = Object.fromEntries(
    Object.entries(LOG_FIELD_MAP).map(([short, long]) => [long, short])
  );
  return new Proxy(raw, {
    get(target, prop) {
      if (typeof prop === 'string' && reverseMap[prop]) {
        return target[reverseMap[prop] as keyof Log];
      }
      return Reflect.get(target, prop);
    },
    set(target, prop, value) {
      if (typeof prop === 'string' && reverseMap[prop]) {
        target[reverseMap[prop] as keyof Log] = value;
        return true;
      }
      return Reflect.set(target, prop, value);
    }
  }) as LogAlias;
}

用这个方案你拿到代理对象后可以直接用长键名读写,底层还是操作原始的短键对象,没有额外的内存开销。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 14:48:03