TypeScript带参数的泛型Promise类型推断异常问题求解
问题原因
你最初的类型定义存在两个问题:
- TS的
type声明语法缺失等号,属于语法错误 - 核心错误是
columns的类型被错误定义为T[],实际应为Column<T>[]
当query无入参时,TS可直接从columns配置项反向推断泛型T的结构,碰巧不会触发推断冲突;给query加入参后,如果不显式标注入参类型,TS会同时从query返回值、columns结构两个位置双向推断泛型T,两边推断结果冲突就会抛出data属性类型不兼容的错误。
你之前给pageSize显式标注number类型后恢复正常,本质是显式标注入参后TS降低了query位置的泛型推断优先级,优先从columns推断T类型才碰巧通过校验,并没有解决类型定义本身的错误。
正确类型写法
TS 5.4及以上版本可直接使用内置的NoInfer工具类型,阻止TS从query属性位置反向推断泛型T,强制仅从columns配置推断T的结构,从根源避免双向推断冲突:
// 列配置类型定义 type Column<T> = { field: keyof T; // 可扩展其他列属性,比如表头名、宽度、自定义渲染函数等 title?: string; width?: number | string; }; type Props<T> = { // 用NoInfer包裹返回值中的T,阻断该位置的泛型反向推断 query: (pageSize: number) => Promise<{ data: NoInfer<T>[]; count: number; }>; // 修正columns类型为Column<T>数组 columns: Column<T>[]; }; // 组件泛型声明示例 function CustomTable<T>(props: Props<T>) { // 组件内部逻辑实现 return null; }
如果使用TS 5.4以下版本,可自行实现NoInfer类型:
type NoInfer<T> = T extends infer U ? U : never;
调用效果
使用上述类型定义后,组件调用时不需要给query的入参显式标注类型,TS会自动完成类型推断和校验:
<CustomTable columns={[{ field: "id" }, { field: "name" }]} query={async (pageSize) => { // pageSize自动推断为number类型,无需手动标注 const res = await fetch(`/api/list?pageSize=${pageSize}`); return res.json(); // 返回的data结构会自动和columns的field做类型校验,字段不匹配会直接报错 }} />
columns中field属性的自动补全、类型校验完全正常query入参pageSize自动推断为number类型- 不会再出现
data属性类型不兼容的编译错误
内容的提问来源于stack exchange,提问作者Mennion
相关产品推荐
相关产品推荐

