如何在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,拥有字段智能提示 } } });
关键修改说明
- 移除
TChild默认值:避免TypeScript直接使用PgTable跳过类型推断,强制从table字段获取子表的具体类型。 - 新增
TChildTables泛型:用该参数映射所有子表的类型,每个键对应一个子表的实际类型。 - 调整
join字段为映射类型:将TChildTables的每个键关联到对应的TJoinResult,确保on函数的child参数类型与子表完全匹配。 - 优化函数泛型推断:让TypeScript根据传入的
table和join自动推导主表TTable和子表集合TChildTables,无需手动指定泛型参数。
内容的提问来源于stack exchange,提问作者Anthony Ma
相关产品推荐
相关产品推荐

