React组件中如何让render参数自动推断对应items的类型?
解决React组件中Tab项render函数的类型推断问题
你的问题核心是当前泛型定义限制了TypeScript的类型推断能力,导致render函数的参数只能被推断为unknown。通过调整泛型结构,可以让TypeScript自动推导每个Tab的items对应的具体类型,让render参数获得正确的类型提示。
解决方案:重构泛型定义
我们需要修改Tab和Notification的泛型约束,让TypeScript能追踪到每个Tab的item具体类型:
- 重构
Tab类型:让它接受单个item类型作为泛型参数,而非数组类型
type Tab<T> = { label: string; items: T[]; // 直接使用单个item类型的数组 render: (item: T) => JSX.Element | null; badgeCount?: StringOrNumber; };
- 调整
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
相关产品推荐
相关产品推荐

