javascript - Typescript-feil med styled-components og AS TS2769: Ingen overbelastning samsvarer med dette kallet


Jeg vil ha en enkel komponent som jeg kan style og sende en prop til output-elementtypen med as. Bruker versjon 5 av styled-components og 4 for TS

Men jeg får følgende TS-feil

TS-feil

No overload matches this call.
  Overload 1 of 2, '(props: Omit<Omit<Pick<DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "key" | keyof HTMLAttributes<...>> & { ...; }, never> & Partial<...>, "theme"> & { ...; } & { ...; }): ReactElement<...>', gave the following error.
    Type 'string' is not assignable to type 'undefined'.
  This JSX tag's 'children' prop expects type 'never' which requires multiple children, but only a single child was provided.  TS2769

    11 |     color: #000;
    12 |   `
  > 13 |   return <Component as={as}>{children}</P>
       |          ^
    14 | }
    15 |

Den viktigste delen av denne feilen er her, tror jeg Type 'string' is not assignable to type 'undefined'. Men min forståelse var at med {as='p'} var dette standardverdien for as?

Komponent

import React, { ReactChildren } from 'react'
import styled from 'styled-components'

export interface TextProps {
  as?: string
  children?: ReactChildren | React.ReactNode | string
}

export const Text = ({ as = 'p', children }: TextProps) => {
  const Component = styled.p`
    color: #000;
  `
  return <Component as={as}>{children}</Component>
}

Svar #1

Denne er litt vanskelig. Først og fremst, for å taste riktig Component som aksepterer as-prop, bør du gi den riktig typning for den as-component. Og det andre problemet er at string er bred nok til å resultere i never-type for alle andre props av <Component as={as as string}>. Inkludert children-prop. Så man må innsnevre typen til as for i det minste kjente HTML-tags (så snart du bare tillater å sende strenger der og ikke egendefinerte React-komponenter).

Så koden din kan omskrives som:

import React, { ReactChildren } from 'react'
import styled from 'styled-components'

type KnownTags = keyof JSX.IntrinsicElements

export interface TextProps {
    as?: KnownTags
    children?: ReactChildren | React.ReactNode | string
}

export const Text = ({ as = 'p', children }: TextProps) => {
    const Component = styled.p`
        color: #000;
    `

    return <Component<typeof as> as={as}>{children}</Component>
}

Relaterte artikler