React组件泛型类型推断总是报错怎么办?
在写一个可复用的表单组件时遇到了类型问题,明明定义了泛型接口,但TypeScript老是提示错误:Type 'string' is not assignable to type 'never'。
我尝试这样定义组件:
interface FormProps<T> {
initialValues: T;
onSubmit: (data: T) => void;
}
function Form<T>({ initialValues, onSubmit }: FormProps<T>) {
const [formData, setFormData] = useState(initialValues);
// ...
return (
<form onSubmit={(e) => {
e.preventDefault();
onSubmit(formData); // 这里报错
}}>
</form>
);
}
然后这样使用:
type UserFormType = {
name: string;
age: number;
};
function App() {
return (
<Form
initialValues={{ name: '', age: 0 }}
onSubmit={(data) => console.log(data.email)} // 这里居然没报错!
/>
);
}
奇怪的是,当我在onSubmit里访问不存在的data.email时TypeScript居然没提示,但formData赋值时却提示类型错误。试过给useState添加类型注解:useState(initialValues),但没用,到底哪里出问题了?
你得强制让泛型从initialValues推导出来,同时给useState加上类型。复制这个:
关键是调用的时候要确保泛型能被推导出来。你可以这样用:
注意:如果你写成
initialValues={{} as UserFormType}或者手动指定泛型<Form<UserFormType>>也可以,但最好让TS自动推导。核心就两点:
1. 给useState加
2. 确保initialValues有明确结构让TS能推导
不然TS根本不知道T长什么样,自然后面用data.email也不会报错——因为它认为data是any或者never。