简体   繁体   English

在 TypeScript 的 React 组件中实现“as”属性

[英]Implement "as" prop in React component in TypeScript

I'm implementing a generic component which accept as prop as any HTML element in TypeScript.我正在实现一个通用组件,它接受 TypeScript 中的任何 HTML 元素as道具。

<Component as='div' {...myProps} {...divProps} />

<Component as='button' {...myProps} {...buttonProps} />

I just get lost while trying to define my component's prop as any HTML element.在尝试将组件的 prop 定义为任何 HTML 元素时,我迷路了。

Please share your advice.请分享您的建议。

Thanks.谢谢。

Use somthing like this:使用这样的东西:

interface IProps {
  as: React.ElementType;
}
export const Component = (props: IProps) => {
  const { as: Cmp = "div", ...rest } = props;

  return <Cmp {...rest} />;
};

Here is a great article about how to do it properly这是一篇关于如何正确执行的好文章

The following article describes building a strongly typed polymorphic component.下面的文章描述了构建一个强类型的多态组件。

Here is a summary of how to do it.以下是如何执行此操作的摘要。 The critical point is to use 2 generic types provided by react, these types are ElementType and ComponentPropsWithoutRef.关键是要使用 react 提供的 2 个泛型类型,这些类型是 ElementType 和 ComponentPropsWithoutRef。 ElementType represents a valid React Component or HTMLElement, ComponentPropsWithoutRef can infer the props of Component or an element. ElementType 表示一个有效的 React Component 或 HTMLElement,ComponentPropsWithoutRef 可以推断出 Component 或元素的 props。

import type { ElementType, ComponentPropsWithoutRef, PropsWithChildren } from "react";

type PolymorphicAsProp<E extends ElementType> = {
  as?: E;
};

type PolymorphicProps<E extends ElementType> = PropsWithChildren<
  ComponentPropsWithoutRef<E>
  & PolymorphicAsProp<E>
>;

const defaultElement = "p";

type TextProps<E extends ElementType = typeof defaultElement> = PolymorphicProps<E> & {
  color?: "primary" | "secondary";
};

function Text<E extends ElementType = typeof defaultElement>({
  as,
  children,
  color = "primary",
  className,
  ...restProps
}: PolymorphicProps<E>) {
  
  const Component = as ?? defaultElement;

  const colorClassName = getColorClassNames(color);

  return (
    <Component
    {...restProps}
    className={[
      className ?? ",
      colorClassName
    ]}>
      {children}
    </Component>
  );
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM