TypeScript使用变量访问对象属性时的类型错误问题
解决变量访问对象属性时
toLowerCase()的类型报错问题 你的代码里的类型判断逻辑写错了:if (el[field] === "string") 是在判断属性值是否等于字符串"string",而不是判断该属性的类型是string,所以TypeScript无法把el[field]的类型从string | number窄化为string,自然会报错。
修正后的基础版本
把判断改成typeof el[field] === 'string',这是TypeScript认可的类型守卫,能正确窄化类型:
type Data = { [key: string]: string | number; }; function filtreTexte(arr: Data[], searchCar: string, field: string): Data[] { return arr.filter((el) => { // 正确判断属性值的类型为string if (typeof el[field] === 'string') { return el[field].toLowerCase().indexOf(searchCar.toLowerCase()) !== -1; } // 非string类型的元素直接过滤掉 return false; }) }
进阶优化:用泛型增强类型安全性
上面的版本虽然解决了报错,但field参数可以传入任意字符串,哪怕Data里不存在这个属性。可以用泛型约束field必须是Data的键,让函数更严谨:
type Data = { [key: string]: string | number; }; // 用泛型K约束field必须是Data的键 function filtreTexte<K extends keyof Data>(arr: Data[], searchCar: string, field: K): Data[] { return arr.filter((el) => { const value = el[field]; if (typeof value === 'string') { return value.toLowerCase().includes(searchCar.toLowerCase()); } return false; }) }
这里还把indexOf(...) !== -1换成了更语义化的includes(),效果完全一致。
为什么直接用具体属性名不会报错?
当你直接写el.name时,若代码上下文已经能让TypeScript推断出该属性的类型是string(或者你提前做了正确的类型判断),就不会触发报错。但如果没有任何类型守卫直接调用toLowerCase(),其实同样会出现类型错误——你之前的代码可能刚好有符合要求的类型推断逻辑,所以没遇到问题。
内容的提问来源于stack exchange,提问作者ThGdfd
相关产品推荐
相关产品推荐

