React 与 TS 结合使用时的技巧总结

使用 TS 泛型来定义通用参数

有些时候会遇到有些业务页面结构是通用的,只是传入页面组件的参数略有不同,这样我们可以使用 TS 的泛型来定义通用参数。具体的实例如下:

type GenericPropsData<T> = {
    
    
  items: T[];
  onClick: (value: T) => void;
};

const GenericProps: React.FC<GenericPropsData<number | string>> = ({
    
    
  items,
  onClick,
}) => {
    
    
  return (
    <div>
      <h2>TS 泛型定义参数</h2>
      {
    
    items.map((item) => {
    
    
        return (
          <div key={
    
    item} onClick={
    
    () => onClick(item)}>
            {
    
    item}
          </div>
        );
      })}
    </div>
  );
};

export default GenericProps;

上述例子中,只是简单列举了泛型为数字或者字符串,泛型还可以定位为其他对象。

使用 TS 限定传入的参数

有些业务场景要求根据在一定条件下传入对应参数,组件中的其他参数为不能传递的情况,或者出现类型的情况时,我们可以考虑使用 TS 的never联合类型来声明定义参数的组件。具体实例如下:

type RandomNumberType = {
    
    
  value: number;
};

type PositiveNumber = RandomNumberType & {
    
    
  isPositive: boolean;
  isNegative?: never;
  isZero?: never;
};

type NegativeNumber = RandomNumberType & {
    
    
  isNegative: boolean;
  isPositive?: never;
  isZero?: never;
};

type Zero = RandomNumberType & {
    
    
  isZero: boolean;
  isPositive?: never;
  isNegative?: never;
};

type RandomNumberProps = PositiveNumber | NegativeNumber | Zero;

const RestrictionProps: React.FC<RandomNumberProps> = ({
    
    
  value,
  isPositive,
  isNegative,
  isZero,
}) => {
    
    
  return (
    <div>
      {
    
    value} {
    
    isPositive && "整数"} {
    
    isNegative && "负数"} {
    
    isZero && "0"}
    </div>
  );
};

export default RestrictionProps;

使用 TS 的 Exclude 去除某些联合类型

我们可以使用 TS 中的 Exclude 来去除某些联合类型的参数,例如下面实例:

type HorizontalPosition = "left" | "center" | "right";
type VerticalPosition = "top" | "center" | "bottom";

/**
 * 组件传入的参数可以有如下这些
 * "left-center" | "left-top" | "left-bottom" | "center" | "center-top" |
 * "center-bottom" | "right-center" | "right-top" | "right-bottom"
 *
 * 我们通过Exclude抛掉了center-center的值
 */
type ToastProps = {
    
    
  position:
    | Exclude<`${
      
      HorizontalPosition}-${
      
      VerticalPosition}`, "center-center">
    | "center";
};

const ExcludeProps: React.FC<ToastProps> = ({
    
     position }) => {
    
    
  return <div>Toast Notification Position - {
    
    position}</div>;
};

export default ExcludeProps;

使用 TS 实现多态组件

type TextOwnProps<E extends React.ElementType> = {
    
    
  size?: "sm" | "md" | "lg";
  color?: "primary" | "secondary";
  children: React.ReactNode;
  as?: E;
};

type TextProps<E extends React.ElementType> = TextOwnProps<E> &
  Omit<React.ComponentProps<E>, keyof TextOwnProps<E>>;

const PolymorphismProps: React.FC<TextProps<React.ElementType>> = ({
    
    
  size,
  color,
  children,
  as,
}) => {
    
    
  const Component = as || "div";
  return (
    <Component className={
    
    `class-with-${
      
      size}-${
      
      color}`}>{
    
    children}</Component>
  );
};

export default PolymorphismProps;

猜你喜欢

转载自blog.csdn.net/qq_33003143/article/details/132778179