如何正确扩展类型,以便其键可以用作TypeScript中依赖属性的索引

xriantvc  于 2023-03-04  发布在  TypeScript
关注(0)|答案(1)|浏览(87)

我正在使用React with TypeScript,并希望执行以下操作:

import React from 'react'
import styles from './SocialNetwork.module.scss'
import classNames from 'classnames'
import { FontAwesomeIcon, type FontAwesomeIconProps } from '@fortawesome/react-fontawesome'

// Generic A doesn't work the way I want it to
export type SocialNetworkProps<A extends keyof JSX.IntrinsicElements> = FontAwesomeIconProps & {
  className?: string
  // I need that if a key from JSX.IntrinsicElements was transferred, then I pull the appropriate type of props from the same type, but already by key.
  as?: A | React.FC,
  asProps?: JSX.IntrinsicElements[A]
}

// In my approach, I need to pass the generic here, and I want it to depend on what the user passed in props
const SocialNetwork: React.FC<SocialNetworkProps> = ({ className, icon, as = 'a', asProps, ...rest }): JSX.Element => {
  const CostumTag = as

  return (
    <CostumTag className={classNames(styles.socialNetwork, className)}>
      <FontAwesomeIcon icon={icon} {...rest} />
    </CostumTag>
  )
}

export default SocialNetwork

我应该如何做,以便当as='div'as='a'字段传递给组件时,asProps类型被拉为JSX.IntrinsicElements['a']

hkmswyz6

hkmswyz61#

我认为我的问题可以被认为是重复的,因为这个问题已经有了答案,事实是,在我的情况下,实现更容易一些,因为我没有.... a a应该动态读取的rest,下面是我如何做到这一点的代码,它对我来说工作得很好:

import React from 'react'
import styles from './SocialNetwork.module.scss'
import classNames from 'classnames'
import { FontAwesomeIcon, type FontAwesomeIconProps } from '@fortawesome/react-fontawesome'

export type SocialNetworkProps<T extends keyof JSX.IntrinsicElements> = FontAwesomeIconProps & {
  className?: string
  as?: T
  asProps?: JSX.IntrinsicElements[T]
}

const SocialNetwork = <T extends keyof JSX.IntrinsicElements>({
  className,
  icon,
  as,
  asProps,
  ...rest
}: SocialNetworkProps<T>): JSX.Element => {
  const CostumTag = (as as React.ElementType) || 'a'

  return (
    <CostumTag className={classNames(styles.socialNetwork, className)} {...asProps}>
      <FontAwesomeIcon icon={icon} {...rest} />
    </CostumTag>
  )
}

export default SocialNetwork

下面是我在编写代码时参考的参考文献的链接:
1.关于堆栈溢出的类似问题-Generic React TypeScript component with 'as' prop (able to render any valid dom node)
1.一篇详细描述如何实现它的文章(我就是从这里开始的)-https://blog.andrewbran.ch/polymorphic-react-components/
1.一个库已经做了类似的事情,但我不会深入研究它-https://blog.andrewbran.ch/polymorphic-react-components/

相关问题