Next.js + TypeScript传递动态类型Props报错解决方法
Next.js + TypeScript 组件Props传递错误解决方案
核心问题分析
你遇到的错误主要来自三个关键问题:
- 类型定义与实际数据不匹配:
Details接口中category_detail被定义为数组类型CategoryDetail[],但实际返回的是单个对象 - 类型窄化失效:
category_name定义为宽泛的string类型,TypeScript无法根据它自动推断category_detail的具体子类型 - 组件调用错误:Props参数拼写错误(
categroy_detail应为category_detail),且错误使用typeof Shirt做类型断言
步骤1:修正类型定义
调整类型结构,让TypeScript能自动做类型窄化,同时匹配实际数据结构:
export interface Box { id: number; details: Details[]; } // 将category_name改为字面量类型,让TS能识别具体类别 export interface Details { id: number; category_name: "shirt" | "bag"; // 修正为单个对象,而非数组,匹配实际返回数据 category_detail: CategoryDetail; } export interface Shirt { id: number; size: string; color: string; } export interface Bag { id: number; width: number; height: number; } export type CategoryDetail = Shirt | Bag;
步骤2:修正组件调用代码
修正拼写错误,利用TypeScript的自动类型窄化特性,无需手动复杂断言:
const Foo: NextPage = () => { const { box } = useFetchBox(); return ( <div> {box.details.map((detail) => ( <> {/* TS会自动根据category_name推断category_detail为Shirt类型 */} {detail.category_name === "shirt" && ( <ShirtDetail category_detail={detail.category_detail} /> )} {/* 同理自动推断为Bag类型 */} {detail.category_name === "bag" && ( <BagDetail category_detail={detail.category_detail} /> )} </> ))} </div> ) }
特殊场景:无法修改类型定义的情况
如果因业务限制不能修改原有类型定义,可通过类型守卫函数实现类型窄化:
// 定义类型守卫,明确判断detail的具体类型 const isShirtDetail = (detail: Details): detail is Omit<Details, 'category_detail'> & { category_detail: Shirt } => { return detail.category_name === "shirt"; }; const isBagDetail = (detail: Details): detail is Omit<Details, 'category_detail'> & { category_detail: Bag } => { return detail.category_name === "bag"; }; // 组件中使用类型守卫 const Foo: NextPage = () => { const { box } = useFetchBox(); return ( <div> {box.details.map((detail) => ( <> {isShirtDetail(detail) && <ShirtDetail category_detail={detail.category_detail} />} {isBagDetail(detail) && <BagDetail category_detail={detail.category_detail} />} </> ))} </div> ) }
内容的提问来源于stack exchange,提问作者ta539tg70
相关产品推荐
相关产品推荐

