如何在TypeScript React组件中自动关联as与asProps类型
解决方案
首先调整类型定义与组件写法,让as和asProps的类型自动关联,无需手动传递泛型:
import React from 'react' import styles from './SocialNetwork.module.scss' import classNames from 'classnames' import { FontAwesomeIcon, type FontAwesomeIconProps } from '@fortawesome/react-fontawesome' // 定义as的可选类型:HTML元素名 或 React函数组件 type AsType = keyof JSX.IntrinsicElements | React.FC<any> // 根据as的类型自动推导asProps的对应类型 type GetAsProps<T extends AsType> = T extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[T] : T extends React.FC<infer P> ? P : never // 关联as与asProps的Props类型,默认as为a标签 export type SocialNetworkProps<T extends AsType = 'a'> = FontAwesomeIconProps & { className?: string as?: T asProps?: GetAsProps<T> } // 用泛型函数组件替代React.FC,让TypeScript自动推导泛型参数 const SocialNetwork = <T extends AsType = 'a'>({ className, icon, as = 'a' as T, asProps, ...rest }: SocialNetworkProps<T>): JSX.Element => { const CustomTag = as || 'a' return ( <CustomTag className={classNames(styles.socialNetwork, className)} {...asProps} > <FontAwesomeIcon icon={icon} {...rest} /> </CustomTag> ) } export default SocialNetwork
关键修改说明:
- 用
AsType统一约束as的取值范围,覆盖HTML标签和自定义组件两种场景 - 通过
GetAsProps条件类型,根据as的实际传入值自动匹配对应的props类型 - 将组件定义为泛型函数,而非
React.FC,让TypeScript自动推导泛型参数,无需手动指定 - 给
as设置默认值'a',确保未传as时asProps默认匹配<a>标签的props类型
使用示例:
// as='a'时,asProps自动匹配<a>的props,可传入href、target等属性 <SocialNetwork icon="facebook" as="a" asProps={{ href: '/facebook', target: '_blank' }} /> // as='div'时,asProps自动匹配<div>的props,可传入role、aria-label等属性 <SocialNetwork icon="twitter" as="div" asProps={{ role: 'button', ariaLabel: 'twitter link' }} /> // 传入自定义组件时,asProps自动匹配组件的props类型 const CustomButton: React.FC<{ onClick: () => void }> = ({ children }) => <button onClick={() => {}}>{children}</button> <SocialNetwork icon="github" as={CustomButton} asProps={{ onClick: () => console.log('clicked') }} />
内容的提问来源于stack exchange,提问作者UKRman
相关产品推荐
相关产品推荐

