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

如何为React插槽组件属性编写正确的TypeScript类型

React组件插槽属性的TypeScript类型优化方案

原始组件代码

interface MyComponentProps<T extends React.ElementType> {
  SlotComponent: T
  slotComponentProps: React.ComponentProps<T>
}

function MyComponent<T extends React.ElementType>({
  SlotComponent,
  slotComponentProps,
}: MyComponentProps<T>): React.ReactNode {
  return (
    <div>
      <SlotComponent {...slotComponentProps} />
      {/* Other things go here. */}
    </div>
  )
}

遇到的问题

  • 尝试将SlotComponent设为可选并默认值设为'button'时,出现TypeScript错误:
    TS2322: Type '"button"' is not assignable to type 'T'.
    '"button"' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'ElementType<any, keyof IntrinsicElements>'.
    
    SlotComponent = 'button',
    ~~~~~~~~~~~~~
    
  • 尝试将slotComponentProps设为可选时,出现TypeScript错误:
    TS2322: Type '{}' is not assignable to type 'LibraryManagedAttributes<T, any>'.
    
    <SlotComponent {...slotComponentProps} />
     ~~~~~~~~~~~~~
    
  • 尝试将slotComponentProps设为可选并添加{}作为默认值时,出现TypeScript错误:
    TS2322: Type '{}' is not assignable to type 'ComponentProps<T>'.
    
    slotComponentProps = {},
    ~~~~~~~~~~~~~~~~~~
    

解决方案

通过调整泛型约束、设置泛型默认值,并结合React内置的属性映射逻辑,可解决所有类型报错问题,同时保证组件灵活性:

修改后的完整代码

import React from 'react';

interface MyComponentProps<T extends React.ElementType = 'button'> {
  SlotComponent?: T;
  slotComponentProps?: Partial<React.LibraryManagedAttributes<T, React.ComponentProps<T>>>;
}

function MyComponent<T extends React.ElementType = 'button'>({
  SlotComponent = 'button' as T,
  slotComponentProps = {},
}: MyComponentProps<T>): React.ReactNode {
  return (
    <div>
      <SlotComponent {...slotComponentProps} />
      {/* Other things go here. */}
    </div>
  );
}

关键修改说明

  1. 泛型默认值处理:给泛型T设置默认值'button',当用户不传入SlotComponent时,TypeScript会自动将T推断为'button'。同时用as T断言默认值类型,解决默认值与泛型的兼容性问题。
  2. 插槽属性类型兼容:使用Partial<React.LibraryManagedAttributes<T, React.ComponentProps<T>>>作为slotComponentProps的类型,LibraryManagedAttributes会处理React内置的属性映射规则(比如className与class的转换),Partial让所有属性变为可选,确保空对象默认值能兼容所有组件的属性类型。
  3. 属性可选性配置:将SlotComponent和slotComponentProps都标记为可选(?),满足灵活传参的需求。

验证场景

  • 无参数调用:自动渲染button组件,无类型报错
    <MyComponent />
    
  • 传入自定义组件:
    const CustomLink = ({ href, children }: { href: string; children: React.ReactNode }) => <a href={href}>{children}</a>;
    <MyComponent SlotComponent={CustomLink} slotComponentProps={{ href: '/test' }} />
    
  • 传入HTML元素:
    <MyComponent SlotComponent="div" slotComponentProps={{ className: 'container' }} />
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 08:15:25