如何使用 Typescript 在 React 中扩展 HTML 属性

Svi*_*ish 7 html attributes dom typescript reactjs

包装简单的 HTML 元素时,以这个MyLink标签为例:

// MyLink.tsx
import React from 'react';
import { Omit } from 'type-zoo';

interface MyLinkProps
  extends Omit<?, 'href'> {
  to: string;
  children: React.ReactNode;
}

export const MyLinkProps: React.FC<MyLinkProps> = ({
  children,
  to,
  ...attributes
}) => (
  <a href={to} {...attributes}>
    {children}
  </a>
);

// Elsewhere
<MyLink to="https://example.com">Example</MyLink>
Run Code Online (Sandbox Code Playgroud)

看来我可以?用以下任何一种来换掉它:

  • React.HTMLProps<HTMLAnchorElement>
  • React.HTMLAttributes<HTMLAnchorElement>
  • React.AnchorHTMLAttributes<HTMLAnchorElement>

但实际上应该在这里使用什么?如果它变化,人们如何选择?

Dan*_*one 11

我会说React.HTMLProps<HTMLAnchorElement>因为这是最具描述性的类型。例如,如果您想为ref锚标记提供属性,则需要使用此类型。

  • 这是我用于反应类型的 goto 资源:https://github.com/piotrwitek/react-redux-typescript-guide (2认同)
  • 谢谢你!基于另一篇专门关于 Divs 的 SO 帖子,我一直在使用 `React.HTMLAttributes&lt;HTMLAnchorElement&gt;` ,它似乎接受除 href 之外的所有 html 属性。我所能收集到的是 React.HTMLProps 允许一组超级属性。 (2认同)

kim*_*udi 6

即使您只是简单地包装 html 元素,我也会选择React.AnchorHTMLAttributes<HTMLAnchorElement>,因为它是扩展最多的接口,并且可以防止打字稿错误

在此示例中,我将 html<a>元素包装在样式组件中。

MyLink.tsx:

import { forwardRef, AnchorHTMLAttributes, HTMLAttributes, HTMLProps } from 'react'
import styled, { StyledComponent } from '@emotion/styled'
import { EmotionJSX } from '@emotion/react/types/jsx-namespace'

type AnchorProps = AnchorHTMLAttributes<HTMLAnchorElement>
// type AnchorProps = HTMLAttributes<HTMLAnchorElement>
// type AnchorProps = HTMLProps<HTMLAnchorElement> // <~ THIS CAUSE ERROR

const StyledAnchor: StyledComponent<AnchorProps> = styled.a`
  color: red;
`

export default forwardRef<
  HTMLAnchorElement,
  AnchorHTMLAttributes<HTMLAnchorElement>
>((props: AnchorProps): EmotionJSX.Element => <StyledAnchor {...props} />)


// Elsewhere

const ref = useRef<HTMLAnchorElement>(null)

<MyLink ref={ref} href="/">my link</MyLink>
Run Code Online (Sandbox Code Playgroud)

如果我选择React.HTMLProps<HTMLAnchorElement>,那么我会收到打字稿错误:

Type 'StyledComponent<{ theme?: Theme | undefined; as?: ElementType<any> | undefined; }, DetailedHTMLProps<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>, {}>' is not assignable to type 'StyledComponent<AnchorProps, {}, {}>'.
  Types of property 'propTypes' are incompatible.
    Type 'WeakValidationMap<{ theme?: Theme | undefined; as?: ElementType<any> | undefined; } & ClassAttributes<HTMLAnchorElement> & AnchorHTMLAttributes<HTMLAnchorElement>> | undefined' is not assignable to type 'WeakValidationMap<AnchorProps> | undefined'.
      Type 'WeakValidationMap<{ theme?: Theme | undefined; as?: ElementType<any> | undefined; } & ClassAttributes<HTMLAnchorElement> & AnchorHTMLAttributes<HTMLAnchorElement>>' is not assignable to type 'WeakValidationMap<AnchorProps>'.
        Types of property 'as' are incompatible.
          Type 'Validator<ElementType<any> | null | undefined> | undefined' is not assignable to type 'Validator<string | null | undefined> | undefined'.
            Type 'Validator<ElementType<any> | null | undefined>' is not assignable to type 'Validator<string | null | undefined>'.
              Type 'ElementType<any> | null | undefined' is not assignable to type 'string | null | undefined'.
                Type 'ComponentClass<any, any>' is not assignable to type 'string'.ts(2322)
Run Code Online (Sandbox Code Playgroud)

所以我总是用React.AnchorHTMLAttributes<HTMLAnchorElement>

以下是反应类型接口:

  • interface HTMLProps<T> extends AllHTMLAttributes<T>, ClassAttributes<T>
  • interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T>
  • interface AnchorHTMLAttributes<T> extends HTMLAttributes<T>