如何为接收JSXElement的函数参数绑定Tab组件Props类型
SolidJS中Tabs组件获取Tab子元素的类型绑定问题
问题场景
现有一个Tab组件,接收title: string; children: JSXElement类型的props,并将props转换为JSXElement返回:
import { JSXElement } from 'solid-js'; const Tab = (props: { title: string; children: JSXElement }) => props as unknown as JSXElement; export default Tab;
在Tabs组件中使用SolidJS的children工具获取子元素时,tab参数的类型被识别为JSXElement,无法直接关联到Tab组件的props类型:
import { For, Show, children, createSignal } from 'solid-js'; import { TabTitle } from '../'; import toArray from '../../utils/toArray'; import { Container, TabsUnorderedList } from './styles'; const Tabs = (props: ITabs) => { const [selectedTab, setSelectedTab] = createSignal(0); const c = children(() => props.children); return ( <Container> <TabsUnorderedList> <For each={toArray(c())}> {/* tab类型为JSXElement,无法直接访问title */} {(tab: any, index) => ( <TabTitle title={tab.title} index={index} activeTab={setSelectedTab} /> )} </For> </TabsUnorderedList> <For each={toArray(c())}> {(tab: any, index) => ( <Show when={index() === selectedTab()} fallback={null}> {tab.children} </Show> )} </For> </Container> ); }; export default Tabs;
解决方案
步骤1:抽离Tab组件的Props类型
首先将Tab的props类型单独抽离并导出,方便在Tabs组件中复用:
import { JSXElement } from 'solid-js'; // 抽离并导出TabProps类型 export type TabProps = { title: string; children: JSXElement }; const Tab = (props: TabProps) => props as unknown as JSXElement; export default Tab;
步骤2:对获取到的子元素做类型断言
由于Tab组件返回的是props强制转换后的JSXElement,TypeScript无法自动识别其真实类型,需要手动将子元素数组断言为TabProps[]:
修改Tabs组件的代码,优化后如下:
import { For, Show, children, createSignal } from 'solid-js'; import Tab, { TabProps } from './Tab'; // 导入TabProps类型 import { TabTitle } from '../'; import toArray from '../../utils/toArray'; import { Container, TabsUnorderedList } from './styles'; const Tabs = (props: ITabs) => { const [selectedTab, setSelectedTab] = createSignal(0); const c = children(() => props.children); // 将子元素数组断言为TabProps[],避免重复调用toArray const tabs = toArray(c()) as TabProps[]; return ( <Container> <TabsUnorderedList> <For each={tabs}> {/* 现在tab的类型为TabProps,可以直接访问title */} {(tab, index) => ( <TabTitle title={tab.title} index={index} activeTab={setSelectedTab} /> )} </For> </TabsUnorderedList> <For each={tabs}> {(tab, index) => ( <Show when={index() === selectedTab()} fallback={null}> {tab.children} </Show> )} </For> </Container> ); }; export default Tabs;
为什么之前的方法无效?
- 使用
ComponentProps<Tab>确实能获取到Tab的props类型,但问题在于children()返回的是Tab组件输出的JSXElement——而你在Tab组件中把props强制转换为了JSXElement,TypeScript无法追踪这个转换后的类型关联,因此必须手动做类型断言来明确子元素的真实类型。
内容的提问来源于stack exchange,提问作者MatejR
相关产品推荐
相关产品推荐

