样式组件 + 打字稿:“as”不可分配给 IntrinsicAttributes 类型

Jas*_*ane 6 javascript typescript reactjs styled-components

我有一个 monorepo,其中包含由样式组件制成的设计系统。在这个设计系统中,我有一个 Heading 组件,它使用 'level' 属性来调整标题的 CSS。

标题

export interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
    level: 'colossus' | 'uber' | 'hero' | '1' | '2' | '3' | '4' | '5'
}

export const Heading: React.FC<HeadingProps> = ({ level = '1', children, ...rest }) => {
    return (
        <HeadingStyled level={level} {...rest}>
            {children}
        </HeadingStyled>
    )
}
Run Code Online (Sandbox Code Playgroud)

用法

要使用这个 Heading 组件,我只需向它传递一个level用于样式和asprop 的参数来调整 HTML 的渲染内容。

<Heading as="h2" level="2">
    Header 2
</Heading>
Run Code Online (Sandbox Code Playgroud)

问题

as当我使用这个组件时,我在prop上收到打字稿错误

Type '{ children: string; as: string; level: "2"; }' is not assignable to type 'IntrinsicAttributes & HeadingProps & { children?: ReactNode; }'.

Property 'as' does not exist on type 'IntrinsicAttributes & HeadingProps & { children?: ReactNode; }'.
Run Code Online (Sandbox Code Playgroud)

我努力了:

export interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {
    level: 'colossus' | 'uber' | 'hero' | '1' | '2' | '3' | '4' | '5'
    as?: React.Element | JSX.Element | JSX.IntrinsicElements
}
Run Code Online (Sandbox Code Playgroud)

Aro*_*ron 8

你很接近了!JSX.IntrinsicElements是一个接口,其是 HTML 标签的标签。它本身并不是所有 HTML 标签的联合。

\n

这意味着您需要做的就是

\n
interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> {\n    // ...\n    as?: keyof JSX.IntrinsicElements // Note the keyof!\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在asTS的签名显示为:

\n
(JSX attribute) HeadingProps.as?: "symbol" | "object" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | ... 156 more ... | undefined\n
Run Code Online (Sandbox Code Playgroud)\n

这意味着您的代码现在将完全按预期工作

\n
<Heading as="h2" level="2"> // No TS errors! \xe2\x9c\x85\n    Header 2\n</Heading>\n
Run Code Online (Sandbox Code Playgroud)\n

TS 游乐场链接

\n