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

如何用TypeScript和React实现基于组件的智能属性类型推导?

实现Alert组件actions的自动类型推导

需求说明

我有一个Alert组件,包含可点击的操作项,这些操作项可以使用Button或Link等不同组件。希望实现以下效果:

<Alert actions={[{ component: Link, props: { /* 仅允许传入Link的属性 */ } }]} />

以及

<Alert actions={[{ component: Button, props: { /* 仅允许传入Button的属性 */ } }]} />

即props的类型能根据component属性自动确定,无需手动添加<Alert<ButtonProps> ... />这类额外泛型,实现类型的自动智能推导。

可行方案(TypeScript实现)

完全可以实现,核心是利用TypeScript的ComponentProps工具类型和泛型数组的自动推断能力,以下是具体实现代码:

1. 基础组件类型定义(示例)

先假设我们有Button和Link组件的类型(如果是第三方库如React Router的Link,直接用其类型即可):

import React from 'react';

// 自定义Button组件类型
type ButtonProps = {
  onClick: () => void;
  children: React.ReactNode;
  variant?: 'primary' | 'secondary';
};
const Button = ({ onClick, children, variant = 'primary' }: ButtonProps) => (
  <button onClick={onClick} className={`btn btn-${variant}`}>{children}</button>
);

// 自定义Link组件类型(或React Router的Link)
type LinkProps = {
  to: string;
  children: React.ReactNode;
  target?: '_blank';
};
const Link = ({ to, children, target }: LinkProps) => (
  <a href={to} target={target} className="link">{children}</a>
);

2. Alert组件的类型与实现

import React from 'react';
import type { ComponentType, ComponentProps } from 'react';

// 定义单个操作项的类型:泛型C表示组件类型,props自动匹配该组件的属性
type ActionItem<C extends ComponentType<any>> = {
  component: C;
  props: ComponentProps<C>;
};

// Alert组件的Props类型:actions是一个由不同ActionItem组成的数组
type AlertProps = {
  message: string;
  actions?: Array<ActionItem<ComponentType<any>>>;
};

// Alert组件实现
const Alert = ({ message, actions = [] }: AlertProps) => (
  <div className="alert">
    <p>{message}</p>
    <div className="alert-actions">
      {actions.map(({ component: Comp, props }, index) => (
        <Comp key={index} {...props} />
      ))}
    </div>
  </div>
);

3. 使用示例(自动类型推导生效)

此时使用Alert组件时,TypeScript会自动根据component的值推断props的类型:

// 传入Link组件时,props只能传入LinkProps的属性
<Alert
  message="请确认操作"
  actions={[
    {
      component: Link,
      props: {
        to: '/confirm',
        children: '确认',
        // 这里如果传入onClick(不属于LinkProps)会直接报错
      }
    }
  ]}
/>

// 传入Button组件时,props只能传入ButtonProps的属性
<Alert
  message="操作成功"
  actions={[
    {
      component: Button,
      props: {
        onClick: () => console.log('关闭'),
        children: '关闭',
        variant: 'secondary'
        // 这里如果传入to(不属于ButtonProps)会直接报错
      }
    }
  ]}
/>

原理说明

  • 利用ComponentProps<C>工具类型,可以直接获取任意React组件C的属性类型;
  • 通过将ActionItem定义为带泛型的类型,让TypeScript在解析actions数组时,自动为每个元素匹配component对应的props类型;
  • 无需手动为Alert组件指定泛型参数,完全由TypeScript自动推断,达到“智能推导”的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:46:06