React TypeScript传递Hotel对象至表单组件时遇类型错误求助
解决React TypeScript中传递Hotel对象的类型错误
错误信息
Type 'undefined' is not assignable to type 'HotelType'.ts(2322) ManageHotelForm.tsx(27, 5): The expected type comes from property 'hotel' which is declared here on type 'IntrinsicAttributes & Props'
错误原因分析
- useQuery返回值的不确定性:
useQuery的data字段在查询未完成、失败或无数据时会是undefined,但ManageHotelForm的Props要求hotel必须是HotelType类型,不允许undefined。 - API返回类型不匹配:前端
fetchHotelById声明返回Promise<HotelType[]>(酒店数组),但后端findOne返回的是单个酒店对象或null,类型完全不匹配。 - 未处理后端返回null的情况:如果数据库中找不到对应酒店,后端会返回
null,但前端类型没包含这种可能。
修复步骤
1. 修正API函数的返回类型
修改fetchHotelById的返回类型,匹配后端实际返回的单个酒店对象或null:
// fetchHotelById export const fetchHotelById = async (hotelId: string): Promise<HotelType | null> => { const response = await fetch(`${API_BASE_URL}/api/my-hotels/${hotelId}`, { credentials: "include" }) if (!response.ok) { throw new Error('Error fetching hotels'); } return response.json(); }
2. 调整表单组件的Props类型
允许hotel为undefined或null,或者在父组件确保传递有效数据后再渲染组件:
// ManageHotelForm.tsx type Props = { onSave: (hotelFormData: FormData)=> void isLoading: boolean, hotel: HotelType | null | undefined, // 允许undefined和null }
或者保持hotel为必填,但在父组件中加条件渲染:
// page.tsx const EditHotel = () => { const {hotelId} = useParams(); const {data:hotel, isLoading} = useQuery("fetchHotelById", ()=> apiClient.fetchHotelById(hotelId || ""),{ enabled: !!hotelId}) // 加载中或无数据时显示占位 if (isLoading) return <div>加载中...</div>; if (!hotel) return <div>未找到酒店</div>; return <ManageHotelForm hotel={hotel} isLoading={isLoading} onSave={/* 你的保存逻辑 */} /> }
3. 修复表单组件中的reset逻辑
因为hotel可能为null或undefined,在useEffect中先判断再执行reset:
// ManageHotelForm.tsx useEffect(()=>{ if (hotel) { // 仅当hotel存在时重置表单 reset(hotel); } },[hotel,reset]);
4. 可选:给useQuery添加类型声明
明确指定useQuery的返回类型,让TypeScript更准确地推断data的类型:
// page.tsx const {data:hotel, isLoading} = useQuery<HotelType | null>( "fetchHotelById", ()=> apiClient.fetchHotelById(hotelId || ""), { enabled: !!hotelId} )
内容的提问来源于stack exchange,提问作者yzkael
相关产品推荐
相关产品推荐

