我有一个react钩子,看起来像这样:
export const useForm = <T>(values: T) => {
const [formData, setFormData] = useState<FormFieldData<T>>({});
useEffect(() => {
const fields = {};
for (const key in values) {
const value = values[key];
fields[key] = {
value,
errorMsg: '',
};
}
setFormData(fields);
}, []);
return {
formData,
};
};
它接受一个包含一些字段和它们的默认值的对象,例如:
const { formData } = useForm({
stringField: '',
numberField: 1,
booleanField: false,
});
它接受这些键和默认值,并使用它们来构建和返回一个对象,formData
:
{
stringField: {
value: '',
errorMsg: '',
},
numberField: {
value: 1,
errorMsg: '',
},
booleanField: {
value: false,
errorMsg: '',
},
}
为了使formData
正确键入,我使用类型FormFieldData
,它接受传递给钩子的泛型类型参数,并使用这些键和值为formData
创建类型:
export type FormField<T> = {
errorMsg: string;
value: T;
};
export type FormFieldData<T> = {
[K in keyof T]: FormField<T[keyof T]>;
};
问题是,formData
中字段对象中每个值的类型是传递给钩子的所有不同类型的联合类型。在上面的例子中,formData.stringField.value
的类型是string | number | boolean
。
我希望每个字段value
属性的类型与传递到钩子的字段的原始值相同,因此formData.stringField.value
为string
,formData.numberField.value
为number
。
我在这里错过了什么?
为什么T[keyof T]
在泛型对象中创建所有类型的联合?
我通过将FormFieldData类型更改为:
来修复此问题export type FormFieldData<T> = {
[K in keyof T]: FormField<T[K]>;
};
我通过将FormFieldData类型更改为:
来修复此问题export type FormFieldData<T> = {
[K in keyof T]: FormField<T[K]>;
};