TS泛型应用场景

目前使用monorepo构建项目,目前划分为ui-core,ui-web,ui-native,ui-core用来统一处理逻辑,而ui-web以及ui-native则主要是网页端以及app端的ui,有些配置,比如

const headerOptions: {
    Icon: FC<IconProps>
    openFn: (v: boolean) => void
    show: boolean
  }[] = [
    {
      Icon: Expand03,
      openFn: () =>
        setMediaData({
          contentFile,
          customSource: CustomMediaSource.GALLERY_PURCHASE_MODAL
        }),
      show: true
    },
    {
      Icon: Edit05,
      openFn: setEditLabel,
      show: true
    }
  ]

这里的IconProps在web端指的是

export interface IconProps extends SVGProps<SVGSVGElement> {
  size?: IconSize
  color?: string
}

而在react-native端则是

import { SvgProps } from "react-native-svg"
import { IconSize } from "./IconSizes"

export interface IconProps extends SvgProps {
  size?: IconSize
  color?: string
}

所以如果我先把这个配置 headerOptions放到ui-core里面,ui-web以及ui-native调用的时候分别指定泛型才比较合适,最后实现代码:

import { FC, useState } from "react"

export type PurchasedContentProps = PurchasedContentCachedProps

interface UsePurchasedContentComponentProps<A>
  extends PurchasedContentCachedProps {
  readonly Expand03: FC<A>
  readonly Edit05: FC<A>
  readonly hoverClass?: string
}

export function usePurchasedContentComponent<A>({
  content,
  Expand03,
  Edit05,
  hoverClass = ""
}: UsePurchasedContentComponentProps<A>) {
  const [editLabel, setEditLabel] = useState(false)

  const { setMediaData } = useMediaModal()
  const contentFile = new ContentFile(content)

  const disableOptions = !content.processed

  let iconClassName = cn(
    !disableOptions
      ? "pointer-events-none text-passes-gray-light/50"
      : "cursor-pointer transition active:opacity-50",
    hoverClass
  )
  if (process.env.IS_REACT_NATIVE) {
    iconClassName = cn(!disableOptions && "text-passes-gray-light/50")
  }

  const headerOptions: {
    Icon: FC<A>
    openFn: (v: boolean) => void
    show: boolean
  }[] = [
    {
      Icon: Expand03,
      openFn: () =>
        setMediaData({
          contentFile,
          customSource: CustomMediaSource.GALLERY_PURCHASE_MODAL
        }),
      show: true
    },
    {
      Icon: Edit05,
      openFn: setEditLabel,
      show: true
    }
  ]

  const { width, height } = content
  const aspectRatio = (width || 1) / (height || 1)

  return {
    aspectRatio,
    iconClassName,
    editLabel,
    setEditLabel,
    headerOptions,
    contentFile,
    setMediaData
  }
}

用的时候指定泛型:

 const {
    contentFile,
    setMediaData,
    aspectRatio,
    iconClassName,
    editLabel,
    setEditLabel,
    headerOptions
  } = usePurchasedContentComponent<IconProps>({
    content,
    Expand03,
    Edit05,
    hoverClass: !isMobile ? "hover:text-passes-gray-light" : ""
  })
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容