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

TypeScript遍历解析对象精简数据时rtn[key]赋值报错

问题背景

开发对象解析逻辑用于剔除冗余嵌套数据时,代码在rtn[key]赋值语句处触发TypeScript类型报错,暂未定位报错原因。

复现代码

type TValueCar = { make: { value: string }; model: { value: string } };
type TCarKey = keyof TValueCar;
type TCar = { make: { value: string }; model: { value: string } };

const parseCarValueObject = (valueObject: TValueCar): TCar => {
  const ObjectKeys = Object.keys(valueObject) as TCarKey[];

  const rtn = {} as TCar;
  ObjectKeys.forEach((key) => {
    rtn[key] = valueObject[key].value;
  });

  return rtn;
};

补充说明(tl;dr)

最终目标是实现该解析函数的泛型版本,当前代码是泛型实现过程中的第一步。已知存在更简单的直接属性赋值实现方案,但该硬编码写法无法支撑通用泛型函数的开发需求,因此不采用:

const rtn = {
    make: valueObject.make.value,
    model: valueObject.model.value
}

报错原因

报错由两个问题共同导致:

  • 类型定义不匹配:定义的TCar类型和入参TValueCar结构完全一致,属性类型均为{ value: string },但赋值语句右侧取的是valueObject[key].value,类型为string,本身就和rtn[key]的声明类型不匹配。
  • 联合类型key的相关性丢失:即使修正TCar为扁平化结构{ make: string; model: string },TS在遍历"make" | "model"联合类型的key时,会独立判定赋值操作左右两侧的key类型,默认认为存在rtn["make"]被赋值valueObject["model"].value的跨key赋值风险,依然会抛出类型错误。
修复方案

非泛型版本快速修复

先修正TCar的类型定义为扁平化结构,TS即可正常识别赋值逻辑,如遇严格模式校验可补充轻量类型断言:

type TCar = { make: string; model: string }; // 修正类型定义

const parseCarValueObject = (valueObject: TValueCar): TCar => {
  const ObjectKeys = Object.keys(valueObject) as TCarKey[];
  const rtn = {} as TCar;
  ObjectKeys.forEach((key) => {
    rtn[key] = valueObject[key].value;
  });
  return rtn;
};

通用泛型版本实现

可直接编写通用泛型方法,自动匹配入参结构返回扁平化后的解析结果,无需硬编码属性名,满足通用解析需求:

// 定义通用嵌套value包装类型
type ValueWrapper<T = unknown> = { value: T };

/**
 * 解析所有属性为{value: xxx}结构的嵌套对象,返回扁平化后的普通对象
 */
const parseValueObject = <T extends Record<PropertyKey, ValueWrapper>>(valueObject: T) => {
  const result = {} as {
    [K in keyof T]: T[K] extends ValueWrapper<infer V> ? V : never
  };

  (Object.keys(valueObject) as (keyof T)[]).forEach((key) => {
    result[key] = valueObject[key].value;
  });

  return result;
};

// 用法示例:TS会自动推导返回值类型为 { make: string; model: string }
const parsedCar = parseValueObject({
  make: { value: "Tesla" },
  model: { value: "Model 3" }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:24:18