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

如何在React中为Lit泛型Web Component传递泛型类型?

解决React封装泛型Lit Web Component的类型传递问题

问题描述

我有一个用Lit编写的Web Component,它的value属性和自定义事件使用了泛型类型:

@customElement('bl-select')
export default class BlSelect<ValueType extends FormValue = string> extends FormControlMixin(LitElement) {

我无法在React中传递这个泛型类型,当前的封装代码如下:

export const BlSelect = React.lazy<ReactWebComponent<BlSelectType, {
  onBlSelect: EventName<CustomEvent<ISelectOption<ValueType>[]>>
}>>(() =>
  customElements.whenDefined('bl-select').then(elem => ({
      default: createComponent<BlSelectType>(
        {
          react: React,
          tagName: 'bl-select',
          elementClass: elem,
          events: {"onBlSelect":"bl-select"}
        }
      )
    })
));

上述代码中的ValueType没有实际作用,我需要让使用这个React封装组件BlSelect的开发者能够传入泛型类型,请问该怎么做?


解决方案

要让React封装的组件支持泛型类型传递,你需要将导出的React组件声明为泛型函数,并关联value属性和事件的类型到泛型参数:

  1. 定义泛型Props类型
    首先创建一个泛型的Props类型,将ValueType作为泛型参数,确保value属性和onBlSelect事件的类型都依赖于这个参数:

    import { ReactWebComponent, EventName } from '@lit/react';
    import type BlSelect from './path/to/bl-select';
    import type { FormValue, ISelectOption } from './path/to/types';
    
    // 定义泛型的React组件Props
    type BlSelectReactProps<ValueType extends FormValue = string> = ReactWebComponent<
      // 覆盖原组件的value属性类型
      Omit<InstanceType<typeof BlSelect<ValueType>>, 'value'> & { value?: ValueType },
      {
        // 让事件回调的参数类型关联到ValueType
        onBlSelect: EventName<CustomEvent<ISelectOption<ValueType>[]>>
      }
    >;
    
  2. 声明泛型React组件
    将导出的BlSelect组件声明为泛型函数,这样使用者在调用时可以指定ValueType:

    export const BlSelect: <ValueType extends FormValue = string>(
      props: BlSelectReactProps<ValueType>
    ) => React.ReactElement = React.lazy(() =>
      customElements.whenDefined('bl-select').then((elem) => ({
        default: createComponent({
          react: React,
          tagName: 'bl-select',
          elementClass: elem,
          events: { "onBlSelect": "bl-select" }
        })
      }))
    );
    
  3. 使用者如何使用
    现在其他开发者可以在使用组件时指定泛型类型,获得完整的类型提示:

    // 示例:使用number类型作为ValueType
    <BlSelect<number>
      value={100}
      onBlSelect={(e) => {
        // e.detail 会被自动推断为 ISelectOption<number>[]
        console.log(e.detail[0].value); // 类型为number
      }}
    />
    

关键说明

  • 通过将导出的组件声明为泛型函数,TypeScript可以在使用者指定泛型参数时,自动推导value属性和事件回调的类型。
  • 使用Omit和类型交叉来覆盖原Web Component的value属性类型,确保和泛型参数保持一致。
  • 无需修改原Lit组件的代码,仅需在React封装层处理泛型类型的传递。

内容的提问来源于stack exchange,提问作者Murat Çorlu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 15:35:14