TypeScript自定义React useForm Hook报TS2345类型不匹配错误
报错原因
TypeScript 默认会将动态键构造的对象的键类型拓宽为string,不会自动收窄为keyof FormStateType,因此无法和Partial<FormStateType>的类型要求匹配,触发TS2345错误。
解决方案
方案1:添加类型断言(改动最小,安全可用)
你已经在逻辑上保证了fieldName是表单状态的合法键,因此可以直接对构造的更新对象做类型断言,修改getTextChangeHandler内的update调用即可:
function getTextChangeHandler(fieldName: FieldName) { return (e: ChangeEvent<HTMLInputElement>) => { update({ [fieldName ]: e.target.value } as Partial<FormStateType>); }; }
方案2:增加泛型约束+显式类型标注(无断言,更严谨)
如果不想使用类型断言,可以通过泛型收窄字段类型,同时对更新对象做显式类型标注:
// 首先给useForm的泛型增加基础约束,方便TS推导 const useForm = <FormStateType extends Record<string, unknown>>(initialValues: FormStateType) => { type FieldName = keyof FormStateType; // ... 其他原有代码保持不变 function getTextChangeHandler<T extends FieldName>(fieldName: T) { return (e: ChangeEvent<HTMLInputElement>) => { const updates: Partial<FormStateType> = { // 如果表单存在非string类型字段,可在此处根据字段类型做值转换 [fieldName]: e.target.value as FormStateType[T] } update(updates); }; } // ... 其他原有代码保持不变 }
如果你的表单所有字段都是string类型,可以把泛型约束进一步修改为FormStateType extends Record<string, string>,就不需要额外对值做类型断言。
内容的提问来源于stack exchange,提问作者Moe
相关产品推荐
相关产品推荐

