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

如何为接收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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 15:48:06