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

React+TypeScript如何根据as prop动态适配不同容器组件的props

解决方案

这个需求完全可以实现,核心思路是通过TypeScript泛型和类型映射,将as参数的取值和对应组件的Props类型绑定,实现动态类型推导。

实现步骤

1. 定义类型映射表

首先建立as参数可选值和对应组件Props的映射关系,同时覆盖原生元素和React Router的Link组件:

import { Link, LinkProps } from "react-router-dom";
import styled from "styled-components";
import React from "react";

type AsTypeMap = {
  button: React.ButtonHTMLAttributes<HTMLButtonElement>;
  a: React.AnchorHTMLAttributes<HTMLAnchorElement>;
  Link: LinkProps;
};

// 泛型Props,自动根据as的取值匹配对应Props
type ActionItemProps<T extends keyof AsTypeMap> = {
  as: T;
  title: string;
  icon: React.ReactNode; // 如果是传图标类名可修改为string类型
} & AsTypeMap[T];

2. 改写为泛型组件

不要使用固定Props的React.FC,直接写泛型函数式组件即可:

const ActionItem = <T extends keyof AsTypeMap>({
  as,
  title,
  icon,
  ...restProps
}: ActionItemProps<T>) => {
  // 动态生成带样式的容器
  const Container = styled(as === "Link" ? Link : as)`
    display: flex;
    align-items: center;
    width: 100%;
    padding: 12px 16px;
    border: none;
    background: transparent;
    cursor: pointer;
    font-size: 14px;
    /* 其余自定义样式 */
  `;

  return (
    <Container {...restProps}>
      <span>{title}</span>
      <div style={{ flex: 1 }} />
      <span>{icon}</span>
    </Container>
  );
};

使用效果

调用组件时TypeScript会根据传入的as值自动提示对应合法属性:

// as为Link时自动提示to、replace等Link组件属性
<ActionItem 
  as="Link"
  to="/profile"
  title="个人中心"
  icon={<ArrowRight />}
/>

// as为a时自动提示href、target等a标签属性
<ActionItem
  as="a"
  href="https://example.com"
  target="_blank"
  title="访问官网"
  icon={<ExternalLink />}
/>

// as为button时自动提示onClick、disabled等按钮属性
<ActionItem
  as="button"
  onClick={() => alert("点击了按钮")}
  disabled={false}
  title="确认操作"
  icon={<Check />}
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 22:51:00