TypeScript泛型方法:动态指定属性生成PickListOption数组
嘿,这个问题其实很好解决,核心就是把你传入的动态属性名直接用作对象的索引访问符,替代原来硬写的description和value就行。不过咱们用TypeScript的话,顺便把类型安全也兼顾上会更稳妥。
先给你看修改后的完整代码,再一步步解释改动点:
// 假设你的IPickListOption和PickListOption是这样定义的(如果已有可忽略) interface IPickListOption { display: any; value: any; } type PickListOption = IPickListOption; public Test<T>(obj: T[], strDisplay: keyof T, strValue: keyof T): PickListOption[] { const pickList: PickListOption[] = []; // 注意:数组直接用forEach遍历元素更直观,之前的Object.keys是遍历数组的索引字符串,没必要 obj.forEach(item => { // 保留你之前的属性存在性检查,避免访问不存在的属性 if (item.hasOwnProperty(strDisplay) && item.hasOwnProperty(strValue)) { const option: IPickListOption = { display: item[strDisplay], // 用传入的strDisplay替代固定的description value: item[strValue] // 用传入的strValue替代固定的value }; pickList.push(option); } }); return pickList; }
关键改动说明:
- 动态属性访问:把
obj[key].description改成item[strDisplay],直接用传入的字符串参数作为对象的属性键,实现动态取值。 - TypeScript类型约束:给
strDisplay和strValue加上keyof T类型,这样调用方法时,TypeScript会强制检查传入的属性名是否属于泛型T的有效属性,避免拼写错误或传错属性名的情况。 - 数组遍历优化:把
Object.keys(obj).forEach改成obj.forEach,因为obj是数组,直接遍历数组元素(每个元素都是T类型的对象)比遍历数组索引字符串更符合逻辑,代码也更简洁。
如果想让返回的PickListOption类型更严格,比如指定display和value的具体类型,还可以把接口改成泛型:
interface IPickListOption<D, V> { display: D; value: V; } public Test<T, D = T[keyof T], V = T[keyof T]>( obj: T[], strDisplay: keyof T, strValue: keyof T ): IPickListOption<D, V>[] { const pickList: IPickListOption<D, V>[] = []; obj.forEach(item => { if (item.hasOwnProperty(strDisplay) && item.hasOwnProperty(strValue)) { const option: IPickListOption<D, V> = { display: item[strDisplay] as D, value: item[strValue] as V }; pickList.push(option); } }); return pickList; }
这样调用时可以手动指定display和value的类型,或者让TypeScript自动推断,进一步提升类型安全性。
内容的提问来源于stack exchange,提问作者izeko
相关产品推荐
相关产品推荐

