如何使用 Typescript 在 React 中扩展 HTML 属性
Posted
技术标签:
【中文标题】如何使用 Typescript 在 React 中扩展 HTML 属性【英文标题】:How to extend HTML attributes in React with Typescript 【发布时间】:2019-09-17 10:21:34 【问题描述】:当包装简单的 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>
看来我可以将?
换成以下任何一种:
React.HTMLProps<HTMLAnchorElement>
React.HTMLAttributes<HTMLAnchorElement>
React.AnchorHTMLAttributes<HTMLAnchorElement>
但实际上应该在这里使用什么?如果不同,如何选择?
【问题讨论】:
【参考方案1】:我会选择React.AnchorHTMLAttributes<HTMLAnchorElement>
,即使你只是简单地包装html元素,因为它是扩展最多的接口并且可以防止打字稿错误
在此示例中,我将一个 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>
如果我选择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)
所以我总是用React.AnchorHTMLAttributes<HTMLAnchorElement>
这里是 react 类型的接口:
interface HTMLProps<T> extends AllHTMLAttributes<T>, ClassAttributes<T>
interface HTMLAttributes<T> extends AriaAttributes, DOMAttributes<T>
interface AnchorHTMLAttributes<T> extends HTMLAttributes<T>
【讨论】:
【参考方案2】:我会说React.HTMLProps<HTMLAnchorElement>
,因为这是最具描述性的类型。例如,如果您想为锚标记提供 ref
属性,则需要使用此类型。
【讨论】:
这似乎很明智,适用于例如<a>
标签。 ? 让我感到困惑的是它不适用于<svg>
。经过一番摆弄之后,似乎必须有React.SVGProps<SVGSVGElement>
,但是是的。你知道任何好的 React Typescript 类型概述吗?文档中似乎根本没有提到。
这是我用于响应类型的 goto 资源:github.com/piotrwitek/react-redux-typescript-guide
谢谢!基于另一篇专门关于 Divs 的 SO 帖子,我一直在使用 React.HTMLAttributes<HTMLAnchorElement>
,它似乎接受除了 href 之外的所有 html 属性。我只能收集到 React.HTMLProps 允许一组超级属性。
当我向我的锚标签提供ref
并在我的示例中使用React.HTMLProps<HTMLAnchorElement>
时,我收到错误消息。 React.HTMLAttributes
或 React.AnchorHTMLAttributes
不会发生这种情况。不过,我将元素包装在样式组件中。但我总是使用React.AnchorHTMLAttributes<HTMLAnchorElement>
而不是您的建议。以上是关于如何使用 Typescript 在 React 中扩展 HTML 属性的主要内容,如果未能解决你的问题,请参考以下文章
如何在 TypeScript 中使用带有 React 无状态功能组件的子组件?
如何使用 Typescript 在 React 中扩展 HTML 属性
React-native:如何在 React-native 中使用(和翻译)带有 jsx 的 typescript .tsx 文件?