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

React组件中如何让render参数自动推断对应items的类型?

解决React组件中Tab项render函数的类型推断问题

你的问题核心是当前泛型定义限制了TypeScript的类型推断能力,导致render函数的参数只能被推断为unknown。通过调整泛型结构,可以让TypeScript自动推导每个Tab的items对应的具体类型,让render参数获得正确的类型提示。

解决方案:重构泛型定义

我们需要修改Tab和Notification的泛型约束,让TypeScript能追踪到每个Tab的item具体类型:

  1. 重构Tab类型:让它接受单个item类型作为泛型参数,而非数组类型
type Tab<T> = {
  label: string;
  items: T[]; // 直接使用单个item类型的数组
  render: (item: T) => JSX.Element | null;
  badgeCount?: StringOrNumber;
};
  1. 调整Notification的泛型与Props类型:用元组类型对应多个不同类型的Tab项
type NotificationProps<TabItems extends unknown[]> = {
  tabs?: { [K in keyof TabItems]: Tab<TabItems[K]> };
  offset?: Offset;
  heading?: string;
  onMarkAllUsRead?(): void;
};

export default function Notification<TabItems extends unknown[]>(
  props: NotificationProps<TabItems>,
) {
  return <div>{props.heading}</div>;
}

修改后的完整代码

import { faker } from "@faker-js/faker";
import * as React from "react";

type StringOrNumber = number | string;

type Offset = {
  top?: StringOrNumber;
  left?: StringOrNumber;
  right?: StringOrNumber;
  bottom?: StringOrNumber;
};

type Tab<T> = {
  label: string;
  items: T[];
  render: (item: T) => JSX.Element | null;
  badgeCount?: StringOrNumber;
};

type NotificationProps<TabItems extends unknown[]> = {
  tabs?: { [K in keyof TabItems]: Tab<TabItems[K]> };
  offset?: Offset;
  heading?: string;
  onMarkAllUsRead?(): void;
};

export default function Notification<TabItems extends unknown[]>(
  props: NotificationProps<TabItems>,
) {
  return <div>{props.heading}</div>;
}

// Example usage:
<Notification
  offset={{
    top: "50px",
  }}
  tabs={[
    {
      label: "Users",
      items: new Array(5).fill(null).map(() => ({
        name: faker.name.fullName(),
        email: faker.internet.email(),
      })),
      render: (user) => {
        // 现在user会自动推断为 { name: string; email: string }
        return null;
      },
    },
    {
      label: "Emails",
      items: new Array(5).fill(null).map(() => ({
        type: faker.random.word(),
        body: faker.lorem.paragraph(),
      })),
      render: (email) => {
        // 现在email会自动推断为 { type: string; body: string }
        return null;
      },
    },
  ]}
/>;

原写法无法推断类型的原因

原来的Tab<T extends unknown[]>把泛型参数T定义为数组类型,当Notification的泛型是Tab<unknown[]>[]时,TypeScript会将每个Tab的T统一推断为unknown[],因此T[number]的结果就是unknown,导致render参数类型丢失。

重构后,Tab的泛型对应单个item类型,Notification的泛型是各个item类型组成的元组,TypeScript可以逐个追踪每个Tab对应的item类型,从而实现自动推断。

内容的提问来源于stack exchange,提问作者JP Calvo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:42:12