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

TypeScript封装DB查询函数时的类型推断问题求助

解决方案:TypeScript类型关联修复

问题根源

你的代码中TypeScript无法将传入的entityName与对应的数据类型做精确绑定,导致泛型推断时把UserData和UserSettings合并成了联合类型,进而在类型检查时出现交叉类型的错误要求,同时调用时的智能提示也会混编两个类型的属性。

修复步骤

  1. 创建表名到数据类型的映射:显式建立表名与对应数据结构的关联,让TypeScript能精准推断类型
  2. 在泛型函数中绑定映射关系:利用映射类型约束EntityName与对应数据类型的关联
  3. 优化create方法的参数类型:自动排除id字段,避免调用者传入冗余参数

修改后的完整代码

// DB Types
type UserData = {
  id: string,
  name: string,
  email: string
}

type UserSettings = {
  id: string,
  language: string,
  country: string
}

type Tables = {
  user: 'user'
  userSettings: 'userSettings'
}

// 新增:表名到对应数据类型的映射,核心修复点
type TableToData = {
  user: UserData;
  userSettings: UserSettings;
};

const dbQueries = {
  user: {
    create: (args: {data: UserData}) => {/* ...queryDB */ },
    read: (userId: string) => {/* ...queryDB */ }
    //... other CRUD queries
  },
  userSettings: {
    create: (args: {data: UserSettings}) => {/* ...queryDB */ },
    read: (userSettingId: string) => {/* ...queryDB */ }
    //... other CRUD queries
  }
}

// 封装所有查询以修改部分方法,并返回特定实体的所有查询(如userSettings的全部查询)
const getModifiedQueriesForEntity = <EntityName extends keyof TableToData>(entityName: EntityName) => {
  const queries = dbQueries[entityName];
  // 明确当前实体对应的数据类型
  type EntityData = TableToData[EntityName];

  // 封装原create方法:无需包裹data,自动生成ID
  const create = (args: Omit<EntityData, 'id'>) => {
    const id: string = getRandomId(); // 返回字符串类型ID
    return queries.create({ data: { ...args, id } as EntityData });
  }

  // 其他查询方法保持不变
  return {
    ...queries,
    create
  }
}

// 测试调用:智能提示仅显示User的属性(name、email)
const {create: createUser} = getModifiedQueriesForEntity('user');
createUser({
  name: 'John',
  email: 'john@example.com'
});

// 测试调用:智能提示仅显示UserSettings的属性(language、country)
const {create: createUserSettings} = getModifiedQueriesForEntity('userSettings');
createUserSettings({
  language: 'zh-CN',
  country: 'CN'
});

关键说明

  • 新增的TableToData映射是核心,它让TypeScript能根据传入的entityName直接定位到对应的数据类型,不再用模糊的联合类型推断
  • 使用Omit<EntityData, 'id'>自动排除id字段,确保调用者不需要手动传入ID,符合需求设计
  • as EntityData类型断言用于告诉TypeScript,{...args, id}的结构完全符合当前实体的数据类型,解决类型不匹配的报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 04:46:47