You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为嵌套对象场景下的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 })));
}

类型优化说明

  1. 移除any类型:将getter的第一个参数从any改为unknown,遵循TypeScript类型安全原则,避免任意类型带来的潜在风险。
  2. 合法索引访问:通过as Record<string, unknown>断言,明确告知TypeScript当前对象支持字符串索引,适配JSON对象的结构特性。
  3. 最终结果断言:因为业务规则明确最终访问值为字符串数组,所以在reduce结束后用as string[]做类型断言,确保后续map操作的类型正确性。
  4. 边界处理:增加了targetObj的存在性判断,避免数组索引越界或目标对象不存在导致的运行时错误。

内容的提问来源于stack exchange,提问作者Kafka4PresidentNow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 23:55:19