You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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'

错误原因分析

  1. useQuery返回值的不确定性:useQuery的data字段在查询未完成、失败或无数据时会是undefined,但ManageHotelForm的Props要求hotel必须是HotelType类型,不允许undefined。
  2. API返回类型不匹配:前端fetchHotelById声明返回Promise<HotelType[]>(酒店数组),但后端findOne返回的是单个酒店对象或null,类型完全不匹配。
  3. 未处理后端返回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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:35:06