簡體   English   中英

使用帶有 typescript 的 props.children 和 styled-component "as" 道具

[英]Using props.children and styled-component "as" prop with typescript

我瀏覽了幾個現有的解決方案和帖子,但實際上找不到任何解決方案。

因此,我將 React 與 Typescript 和樣式組件一起使用。

我的項目的一部分是Heading組件。 理想情況下,我想像<Heading level={2}>Hello world!</Heading>一樣在需要的地方使用它。

這是它的簡化 Codesandbox 代碼

然而, <S.Heading在我的 Linter 中拋出了錯誤,盡管它似乎在視覺上起作用。

錯誤

這個 JSX 標簽的 'children' 屬性期望類型 'never' 需要多個孩子,但只提供了一個孩子。ts(2745)

沒有重載匹配此調用。 這個 JSX 標記的 'children' 屬性需要類型 'never',它需要多個孩子,但只提供了一個孩子。ts(2769)

不確定我的代碼有什么問題,因為我認為我遵循了大多數建議..

Typescript 模板文字類型並不像您想象的那么聰明。 您可能期望h${props.level}評估為聯合類型"h1" | "h2" |... "h1" | "h2" |...基於你的props.level變量的類型。 相反,它只是string 因此,您需要在代碼中的某處使用as斷言,以聲明此stringJSX.IntrinsicElements的有效鍵。

獲得聯合"h1" | "h2" |... "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"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM