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
相关产品推荐
相关产品推荐

