TypeScript中根据接口属性键获取泛型值类型作为函数参数类型
TypeScript中绑定接口键与函数参数类型的解决方案
你遇到的问题是:当使用泛型接口定义Row时,key和render函数的value类型没有形成绑定,导致value变成了所有可能值类型的联合,而不是对应key的具体类型。
问题根源
原来的写法中,Row<DumpRecord>的泛型K默认是keyof DumpRecord(即"arr"|"num"|"str"),此时key是联合类型,render的value也是T[K]对应的联合类型。TypeScript无法自动关联key的具体值和value的类型,因为两者都是独立的联合成员。
解决方案:生成绑定键与参数类型的联合类型
通过映射类型生成每个键对应的具体Row类型的联合,让TypeScript能自动推断key和value的关联关系:
type RowType = Record<string, any> // 工具类型:遍历T的所有键,生成每个键对应的Row类型,最终返回联合类型 type Row<T extends RowType> = { [K in keyof T]: { key: K render: (value: T[K], row: T) => any } }[keyof T] // 修正原接口的语法错误(去掉多余的=) interface DumpRecord { arr: string[], num: number, str: string } // 自动推断:key为'arr'时,value类型是string[] let rowArr: Row<DumpRecord> = { key: 'arr', render: (value, row) => { value.push('new item'); // 类型校验通过 } } // 自动推断:key为'num'时,value类型是number let rowNum: Row<DumpRecord> = { key: 'num', render: (value, row) => { console.log(value.toFixed(2)); // 类型校验通过 } } // 错误示例:key与value类型不匹配时会报错 let invalidRow: Row<DumpRecord> = { key: 'str', render: (value: number) => {} // TypeScript报错:类型不兼容 }
备选方案:显式指定泛型键
如果需要更明确的类型声明,可以显式指定Row的第二个泛型参数K,强制绑定key和value的类型:
type RowType = Record<string, any> interface Row<T = RowType, K extends keyof T = keyof T> { key: K render: (value: T[K], row: T) => any } interface DumpRecord { arr: string[], num: number, str: string } // 显式指定K为'arr',value自动对应string[]类型 let rowArr: Row<DumpRecord, 'arr'> = { key: 'arr', render: (value, row) => { value.push('test'); } }
内容的提问来源于stack exchange,提问作者hambos22
相关产品推荐
相关产品推荐

