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
相关产品推荐
相关产品推荐

