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

Next.js + TypeScript传递动态类型Props报错解决方法

Next.js + TypeScript 组件Props传递错误解决方案

核心问题分析

你遇到的错误主要来自三个关键问题:

  1. 类型定义与实际数据不匹配:Details接口中category_detail被定义为数组类型CategoryDetail[],但实际返回的是单个对象
  2. 类型窄化失效:category_name定义为宽泛的string类型,TypeScript无法根据它自动推断category_detail的具体子类型
  3. 组件调用错误: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 09:15:29