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

Typescript+React如何实现适配字典类型的通用文本输入变更处理函数?

错误原因

你遇到的Spread types may only be created from object types. ts(2968)报错,是因为TypeScript编译器无法确定通过动态索引fieldName取到的prevData[fieldName]是可展开的对象类型。即使你在MyEntity中定义所有字段都是StringLanguage字典类型,TypeScript在处理动态索引访问场景时,默认不会做全局字段类型推导,因此会抛出类型错误。

解决方案

方案1:简单类型断言(适合小项目/确定MyEntity所有字段都是StringLanguage的场景)

直接对动态索引取到的值做类型断言,告诉编译器它是可展开的StringLanguage类型即可:

const handleChange2 = (fieldName: keyof MyEntity) => (
  e: React.ChangeEvent<HTMLInputElement>
) => {
  setData((prevData) => { 
    return {
      ...prevData, 
      [fieldName]: {
        // 加类型断言告诉编译器该值是StringLanguage类型
        ...(prevData[fieldName] as StringLanguage),
        [selectedLanguage]: e.currentTarget.value 
      }
    };
  });
};

方案2:泛型约束(更严谨,适合大项目/MyEntity字段类型可能变更的场景)

通过泛型约束限制传入的fieldName对应的字段必须是StringLanguage类型,从根源避免类型错误,后续如果误传入非StringLanguage类型的字段名,TypeScript会直接在调用阶段报错:

const handleChange2 = <T extends keyof MyEntity>(
  fieldName: MyEntity[T] extends StringLanguage ? T : never
) => (
  e: React.ChangeEvent<HTMLInputElement>
) => {
  setData((prevData) => { 
    return {
      ...prevData, 
      [fieldName]: {
        ...prevData[fieldName],
        [selectedLanguage]: e.currentTarget.value 
      }
    };
  });
};

调用方式修正

你当前的调用写法存在参数传递错误,由于handleChange2是柯里化函数,传入字段名后返回的就是直接接收事件对象的回调,不需要额外套一层箭头函数:

// 修正后
onChange={handleChange2("name")}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 13:06:03