动态循环中如何检测类型以避免调用trim等无效函数?
问题解决方案
我编写了一个循环,用于对访问到的facility对象属性的所有字符串值执行trim()操作。但facility对象包含一个AdditionalInfo属性,该属性是复杂对象而非字符串。我需要让函数仅对字符串类型的值执行trim(),避免在非字符串值上调用trim()。我在下方循环中添加了typeof检测,但实现存在问题,出现了编译器报错。请问应该如何修改该循环才能实现上述需求?
原代码:
fieldNames.forEach(x => { let propVal = ''; let stringVal = ''; if (facility && (x != fieldName)) { if ((typeof facility[x]) == "string") { facility[x] = (facility[x] || '').trim(); } } });
你遇到的编译器报错大概率是类型校验导致的,常见于TypeScript开发场景,诱因包括:索引访问的键类型不匹配、联合类型属性赋值时类型不兼容、严格模式下未校验属性是否存在。可以根据自己的需求选择对应修改方案:
场景1:仅需要处理facility顶层的字符串属性,不需要递归处理AdditionalInfo内部的字段
修改后代码如下:
fieldNames.forEach(x => { // 提前过滤非法情况,简化嵌套逻辑 if (!facility || x === fieldName || !(x in facility)) return // 类型断言:告知编译器x是facility的合法键 const key = x as keyof typeof facility const currentVal = facility[key] if (typeof currentVal === 'string') { // 赋值时增加类型断言解决联合类型兼容报错 facility[key] = currentVal.trim() as never } })
修改说明:
- 如果你使用的是纯JavaScript,无需添加类型断言,直接使用如下简化代码即可,
x in facility的校验可以解决访问不存在属性的告警:fieldNames.forEach(x => { if (!facility || x === fieldName || !(x in facility)) return const currentVal = facility[x] if (typeof currentVal === 'string') { facility[x] = currentVal.trim() } }) - 如果你使用的是TypeScript,类型断言用于解决索引访问、属性赋值两个环节的类型校验问题
- 移除冗余的
|| ''兜底逻辑,已经通过typeof判定为字符串类型,不存在空值需要兜底的情况 - 移除未使用的
propVal、stringVal变量,避免变量声明未使用的告警
场景2:需要递归处理AdditionalInfo等复杂对象内部的所有字符串属性
可以将trim逻辑抽为递归函数,代码如下:
// 递归处理对象所有层级的字符串属性trim function deepTrim(obj: Record<string, any>) { for (const key in obj) { const val = obj[key] if (typeof val === 'string') { obj[key] = val.trim() } else if (typeof val === 'object' && val !== null) { deepTrim(val) } } } fieldNames.forEach(x => { if (!facility || x === fieldName || !(x in facility)) return const key = x as keyof typeof facility const currentVal = facility[key] if (typeof currentVal === 'string') { facility[key] = currentVal.trim() as never } else if (typeof currentVal === 'object' && currentVal !== null) { deepTrim(currentVal) } })
修改说明:
- 递归逻辑会自动跳过非对象非字符串类型的值,不会对Number、Boolean、null等类型做处理
- 无需额外针对AdditionalInfo做特殊判断,所有复杂对象属性都会被递归遍历处理
内容的提问来源于stack exchange,提问作者iron.man.rball
相关产品推荐
相关产品推荐

