如何为嵌套对象场景下的reduce方法及回调指定正确TypeScript类型
TypeScript动态嵌套对象访问的类型优化方案
需求背景
组件接收带索引的点分隔访问键(如"[0].key12.key56.key99")和无明确类型的API返回JSON数组,需从数组中提取指定路径的字符串数组,转换为Array<{ label: string; value: string }>格式更新状态。现有代码已可运行,但getter函数使用了any类型,需优化为符合TypeScript类型安全的写法。
优化后的代码
import { useState } from 'react'; // API返回的无明确类型数组 const apiResponse: unknown[] = [{key1: {key2: {key3: ['a', 'b', 'c']}}}, {key15: {key26: {key37: ['d', 'f', 'g']}}}] const accessorKey = "[0].key1.key2.key3"; const [stateData, setStateData] = useState<Array<{ label: string; value: string }>>([]); // 替换any为unknown,通过类型断言保证索引访问的合法性 const getter = (obj: unknown, key: string): unknown => { return (obj as Record<string, unknown>)[key]; }; const accessorRegex = /^(?:\[(?<index>\d)\])?\.?(?<key>[\w.]+)$/; const matchResult = accessorRegex.exec(accessorKey); const { index, key } = matchResult?.groups || {}; if (index && key) { const targetIndex = parseInt(index, 10); const targetObj = apiResponse[targetIndex]; // 提前判断避免undefined报错 if (!targetObj) return; // 断言最终结果为字符串数组(已知业务规则保证) const targetArray = key.split('.').reduce(getter, targetObj) as string[]; setStateData(targetArray.map(item => ({ label: item, value: item }))); }
类型优化说明
- 移除
any类型:将getter的第一个参数从any改为unknown,遵循TypeScript类型安全原则,避免任意类型带来的潜在风险。 - 合法索引访问:通过
as Record<string, unknown>断言,明确告知TypeScript当前对象支持字符串索引,适配JSON对象的结构特性。 - 最终结果断言:因为业务规则明确最终访问值为字符串数组,所以在
reduce结束后用as string[]做类型断言,确保后续map操作的类型正确性。 - 边界处理:增加了
targetObj的存在性判断,避免数组索引越界或目标对象不存在导致的运行时错误。
内容的提问来源于stack exchange,提问作者Kafka4PresidentNow
相关产品推荐
相关产品推荐

