如何为TypeScript泛型Record定义当前对象的回调参数类型?
解决TypeScript中defineConfig函数的回调参数类型匹配问题
要让defineConfig中每个key对应的cell回调参数自动匹配对应data数组的元素类型,需要调整函数的泛型约束和参数类型,具体修改如下:
核心修改点
将defineConfig的泛型参数改为接收任意包含data数组的对象,然后通过映射类型为每个key推导对应的回调参数类型:
export type InnerEventObject = { id: string | number; a: number; }; export type EventObject<T> = InnerEventObject & T; // 保留原CombinedData类型(如果仍需使用) type CombinedData<T> = Readonly< Record<string, Readonly<{ data: EventObject<T>[] }>> >; // 修改defineConfig的泛型和参数类型 export function defineConfig<D extends Record<string, { data: readonly any[] }>>( props: { [K in keyof D]: { cell: (event: D[K]['data'][number]) => void; }; } ) { return props; }
为什么原写法不生效?
原代码中CombinedData<T>强制所有属性的data都是EventObject<T>[],而泛型约束D extends CombinedData<InnerEventObject>会把每个data的类型收窄为EventObject<InnerEventObject>[],丢失了Data1/Data2的具体字段信息,导致无法推导正确的回调参数类型。
使用验证
修改后,原示例中的config会自动推导正确的类型:
import { defineConfig, type EventObject } from "../types"; type Data1 = { b: string; }; type Data2 = { c: string; }; const data1: EventObject<Data1>[] = [ { id: 1, a: 1, b: "string" }, { id: 2, a: 2, b: "string" }, ]; const data2: EventObject<Data2>[] = [ { id: 1, a: 1, c: "string" }, { id: 2, a: 2, c: "string" }, ]; export const data = { data1: { data: data1 }, data2: { data: data2 }, } as const; export const config = defineConfig<typeof data>({ data1: { cell: (event) => { // event 自动推导为 EventObject<Data1>,可直接访问 b 属性 console.log(event.b); }, }, data2: { cell(event) { // event 自动推导为 EventObject<Data2>,可直接访问 c 属性 console.log(event.c); }, }, });
此时data1的cell参数event会被正确推导为EventObject<Data1>,data2的则为EventObject<Data2>,完全匹配需求。
内容的提问来源于stack exchange,提问作者Syarx
相关产品推荐
相关产品推荐

