【问题标题】:Using props.children and styled-component "as" prop with typescript使用带有 typescript 的 props.children 和 styled-component “as” prop
【发布时间】:2021-07-13 04:01:50
【问题描述】:

我浏览了几个现有的解决方案和帖子,但实际上找不到任何解决方案。

所以,我将 React 与 Typescript 和 styled-component 一起使用。

我的项目的一部分是Heading 组件。理想情况下,我想像<Heading level={2}>Hello world!</Heading> 一样在任何需要的地方使用它。

Here is the simplified Codesandbox Code of it

但是,<S.Heading 在我的 Linter 中引发了错误,尽管它在视觉上似乎可以正常工作。

错误

这个 JSX 标签的 'children' 属性期望类型 'never' 需要多个孩子,但只提供了一个孩子。ts(2745)

没有重载匹配这个调用。 这个 JSX 标签的 'children' 属性期望类型 'never' 需要多个孩子,但只提供了一个孩子。ts(2769)

不确定我的代码有什么问题,因为我认为我遵循了大多数建议..

【问题讨论】:

    标签: reactjs typescript styled-components


    【解决方案1】:

    Typescript template literal types 并不像你想象的那么聪明。您可能期望 h${props.level} 根据您的 props.level 变量的类型评估为联合类型 "h1" | "h2" | ...。相反,它只是string。因此,您需要在代码中的某处使用as 断言,以声明此stringJSX.IntrinsicElements 的有效键。

    将联合 "h1" | "h2" | ... 作为一个类型很难,因为 Props['level']number 文字而不是 string 文字的联合。但是我们并不真正需要联合,因为它是哪种标题类型并不重要。你可以使用as "h1",你会没事的。

    export default function Heading(props: Props) {
      return <S.Heading as={`h${props.level}` as "h1"}>{props.children}</S.Heading>;
    }
    

    出于好奇,我想看看是否可以从JSX.IntrinsicElements 中提取有效的h* 标签。我想出了一个几乎基于字符串长度工作的解决方案,但我忘记了hr

    type HTag = {
        [K in keyof JSX.IntrinsicElements]: K extends `h${string}${infer B}` ? B extends "" ? K : never : never
    }[keyof JSX.IntrinsicElements]
    

    评估为:

    "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "hr"
    

    【讨论】:

    猜你喜欢
    • 2019-11-12
    • 2021-01-11
    • 2018-04-15
    • 2021-11-25
    • 2021-11-13
    • 2019-07-28
    • 2021-10-05
    • 2020-12-30
    • 2020-03-09
    相关资源
    最近更新 更多