如何从组件props中推导FormValueType类型?
解决方案
问题出在你把BasicForm的props固定为FormProps<AnyObject>,手动锁定了FormValueType的类型,导致TypeScript无法从initialValue自动推导。只需将组件改为泛型函数组件,就能实现类型自动推断。
修改后的完整代码
import { useState, ReactNode, createContext, Dispatch, SetStateAction } from 'react'; export type AnyObject = { [k: string]: any; }; // 定义泛型Props接口,限制FormValueType为对象类型 interface FormProps<FormValueType extends AnyObject> { children?: ReactNode; initialValue: FormValueType; onChange?: (value: FormValueType) => void; } // 定义FormContext的类型结构 type FormContextValue<T extends AnyObject> = { formState: T; setFormState: Dispatch<SetStateAction<T>>; }; export const FormContext = createContext<FormContextValue<AnyObject>>({ formState: {}, setFormState: () => {}, }); // 将组件声明为泛型函数 export const BasicForm = <T extends AnyObject>({ children, initialValue, onChange }: FormProps<T>) => { const [formState, setFormState] = useState<T>(initialValue); // 可选:封装setFormState,同步触发onChange回调 const updateFormState = (newState: SetStateAction<T>) => { setFormState(prev => { const updated = typeof newState === 'function' ? newState(prev) : newState; onChange?.(updated); return updated; }); }; return ( <FormContext.Provider value={{ formState, setFormState: updateFormState }}> {children} </FormContext.Provider> ); };
关键说明
- 泛型组件声明:通过
<T extends AnyObject>让组件接收泛型参数,TypeScript会自动根据传入的initialValue推导T的具体类型。 - 状态类型绑定:给
useState显式指定泛型T,确保表单状态类型与initialValue完全一致。 - Context类型兼容:如果需要Context也严格匹配当前表单类型,可以在使用
useContext时指定泛型:const { formState } = useContext<FormContextValue<{ name: string; age: number }>>(FormContext);
使用示例
此时传入initialValue后,onChange的参数类型会自动推导,无需手动指定:
<BasicForm initialValue={{ username: '', email: '' }} onChange={(value) => { // value类型自动推导为 { username: string; email: string } console.log(value.username, value.email); }} > {/* 子组件 */} </BasicForm>
内容的提问来源于stack exchange,提问作者yevt
相关产品推荐
相关产品推荐

