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

Posted

技术标签:

【中文标题】样式组件 + 打字稿:“as”不可分配给类型 IntrinsicAttributes【英文标题】:Styled components + typescript: "as" is not assignable to type IntrinsicAttributes 【发布时间】:2021-04-20 17:26:36 【问题描述】:

我有一个 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>
    )

用法

要使用这个 Heading 组件,我只需将 level 传递给它以设置样式,并传递 as 属性来调整呈现的 HTML。

<Heading as="h2" level="2">
    Header 2
</Heading>

问题

当我使用这个组件时,我在as 道具上遇到打字错误

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; '.

我试过了:

export interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> 
    level: 'colossus' | 'uber' | 'hero' | '1' | '2' | '3' | '4' | '5'
    as?: React.Element | JSX.Element | JSX.IntrinsicElements

【问题讨论】:

不应该是as?: React.Element | JSX.Element | JSX.IntrinsicElements | string 不管我把错误Property 'as' does not exist on type 'IntrinsicAttributes &amp; HeadingProps &amp; children?: ReactNode; '. 保持不变 重启打字稿/捆绑器 使用 React.FC 不是 recommended,并且在 React 网站上没有找到它的当前文档。如果它是一个选项,也许尝试在 Typescript 中实现常规函数或类组件。 您到底想做什么?你想透明地传递所有样式组件道具吗?还是只有as 道具? 【参考方案1】:

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

这意味着你需要做的就是

interface HeadingProps extends HTMLAttributes<HTMLHeadingElement> 
    // ...
    as?: keyof JSX.IntrinsicElements // Note the keyof!

现在as的签名被TS显示为:

(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

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

<Heading as="h2" level="2"> // No TS errors! ✅
    Header 2
</Heading>

TS playground link

【讨论】:

@Jason McFarlane 这个解决方案是不完整的,并且不像as prop 那样运行,因为as 更改了通用样式组件的可用props。它比建议的接口复杂得多。 github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/… @ŁukaszSzcześniak 当然,但这不在最初的问题中

以上是关于样式组件 + 打字稿:“as”不可分配给类型 IntrinsicAttributes的主要内容,如果未能解决你的问题,请参考以下文章

打字稿:类型'null'不可分配给类型错误

打字稿 - 字符串'不可分配给类型'FC

打字稿类型'字符串| null' 不可分配给类型 'string'

类型“数字”不可分配给类型“日期” - 打字稿未编译

打字稿,JSON.parse 错误:“类型 'null' 不可分配给类型 'string'。”

打字稿 - 类型'值:数字;日期:日期; ' 不可分配给类型 'Record[]'。 ts(2322)