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

如何在TypeScript泛型中正确推断父表与子表类型?

解决TypeScript中关联表类型推断问题

你遇到的核心问题是TJoinResult的TChild泛型参数因默认值被固定为PgTable,导致on函数无法获取子表的具体类型提示。通过调整泛型结构,让TypeScript从每个join项的table字段自动推断TChild,同时保持TParent与主表类型的关联,即可解决该问题。

修改后的完整代码

type PgTable = {
  [k: string]: any;
};

// 移除TChild的默认值,强制由上下文推断具体类型
type TJoinResult<TParent extends PgTable, TChild extends PgTable> = {
  table: TChild;
  type: "inner" | "left" | "right";
  on: (parent: TParent, child: TChild) => string;
};

// 新增TChildTables泛型,映射所有子表的类型集合
type TableParams<TTable extends PgTable, TChildTables extends Record<string, PgTable>> = {
  table: TTable;
  join: {
    [K in keyof TChildTables]: TJoinResult<TTable, TChildTables[K]>;
  };
};

// 调整函数泛型,让TypeScript自动推导主表和子表类型
function typeParams<TTable extends PgTable, TChildTables extends Record<string, PgTable>>(
  params: TableParams<TTable, TChildTables>
) {
  // do stuff
}

const userTable = {
  id: "12345",
  firstName: "Bob",
  age: 45
} satisfies PgTable;

const petsTable = {
  id: "123456",
  name: "Charlie",
  owner: "12345" // FK
} satisfies PgTable;

typeParams({
  table: userTable,
  join: {
    pets: {
      table: petsTable,
      type: "inner",
      on: (parent, child) => `${parent.id} = ${child.owner}` // child现在会被正确推断为typeof petsTable,拥有字段智能提示
    }
  }
});

关键修改说明

  1. 移除TChild默认值:避免TypeScript直接使用PgTable跳过类型推断,强制从table字段获取子表的具体类型。
  2. 新增TChildTables泛型:用该参数映射所有子表的类型,每个键对应一个子表的实际类型。
  3. 调整join字段为映射类型:将TChildTables的每个键关联到对应的TJoinResult,确保on函数的child参数类型与子表完全匹配。
  4. 优化函数泛型推断:让TypeScript根据传入的table和join自动推导主表TTable和子表集合TChildTables,无需手动指定泛型参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 11:55:33