React+TypeScript中TS(2322):string类型无法分配给Billboard类型问题
问题背景
我正在使用TypeScript开发React应用,在传递属性给Billboard组件时遇到了类型错误,不清楚如何解决。
在CategoryPage组件中向Billboard组件传递billboard属性时,@/components/ui/billboard.tsx文件出现以下错误:
Type 'string' is not assignable to type 'Billboard'.ts(2322) billboard.tsx(4, 5): The expected type comes from property 'data' which is declared here on type 'IntrinsicAttributes & BillboardProps' (property) BillboardProps.data: Billboard
代码片段
Billboard组件代码(@/components/ui/billboard.tsx)
import { Billboard } from "@/types" interface BillboardProps { data: Billboard; }; const Billboard: React.FC<BillboardProps> = ({ data }) => { console return ( <div>{data.label}</div> ) } export default Billboard;
类型定义(@/types)
export interface Billboard { id: string; label: string; imageUrl: string } export interface Category { id: string; name: string; billboard: string; }
CategoryPage组件代码(@/app/routes/category/[categoryId]/page.tsx)
import Billboard from "@/components/ui/billboard"; import getCategory from "@/actions/get-category"; interface CategoryPageProps { // values } const CategoryPage: React.FC<CategoryPageProps> = async ({ params, searchParams }) => { const category = await getCategory(params.categoryId) return ( <Billboard data={category.billboard} /> // ⚠️ <-- 错误出现在data处 ) } export default CategoryPage;
getCategory函数代码(@/actions/get-category.ts)
import { Category } from "@/types"; const URL = `${process.env.NEXT_PUBLIC_API_URL}/categories`; const getCategory = async (id: string): Promise<Category> => { const res = await fetch (`${URL}/${id}`); return res.json(); }; export default getCategory;
错误提示显示传递给Billboard组件的data属性(即category.billboard)是string类型,而组件期望的是Billboard类型。
疑问
- 为什么category.billboard被推断为string类型而非Billboard类型?
- 如何修复该类型错误,确保传递正确的类型给Billboard组件?
解答
1. 类型推断为string的原因
你的Category接口明确将billboard字段定义为string类型,同时getCategory函数声明返回Promise<Category>,TypeScript会严格按照这个类型定义进行推断,所以category.billboard会被识别为string类型——哪怕后端实际返回的是完整的Billboard对象,类型定义和实际数据结构不匹配才导致了这个问题。
2. 修复方案
根据后端实际返回的数据结构,分两种情况处理:
情况一:后端返回的Category对象中包含完整的Billboard数据
直接修改@/types中的Category接口,将billboard的类型从string改为Billboard:
export interface Category { id: string; name: string; billboard: Billboard; // 修改这里的类型 }
修改后,TypeScript会正确推断category.billboard为Billboard类型,传递给Billboard组件时就不会报错。
情况二:后端仅返回Billboard的ID字符串
这种情况下需要额外请求对应的Billboard数据,再传递给组件:
- 新增获取Billboard的action(比如
@/actions/get-billboard.ts):
import { Billboard } from "@/types"; const URL = `${process.env.NEXT_PUBLIC_API_URL}/billboards`; const getBillboard = async (id: string): Promise<Billboard> => { const res = await fetch(`${URL}/${id}`); return res.json(); }; export default getBillboard;
- 在CategoryPage组件中调用该action获取完整数据:
import Billboard from "@/components/ui/billboard"; import getCategory from "@/actions/get-category"; import getBillboard from "@/actions/get-billboard"; interface CategoryPageProps { // values } const CategoryPage: React.FC<CategoryPageProps> = async ({ params, searchParams }) => { const category = await getCategory(params.categoryId); // 根据billboard ID获取完整数据 const billboardData = await getBillboard(category.billboard); return ( <Billboard data={billboardData} /> // 传递完整的Billboard对象 ) } export default CategoryPage;
同时保持Category接口中billboard的string类型不变,因为它确实只是ID。
内容的提问来源于stack exchange,提问作者volfcan
相关产品推荐
相关产品推荐

