I would like a simple component that I can style and pass a prop the output element type with as. Using version 5 of styled-components and 4 for TS
However I get the following TS error
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 |
The key part of this error is here I believe Type 'string' is not assignable to type 'undefined'. However my understanding was that with the {as = 'p'} this was the default value for as?
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>
}
This one is kind of tricky. First of all, to type correctly Component accepting as prop you should give it correct typing for that as-component. And the second problem is string is wide enough to result in never type for any other props of <Component as={as as string}>. Including children prop. So one has to narrow the type of as for at least known html tags (as soon as you're allowing to pass only strings there and not custom react components).
So your code may be rewritten as:
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>
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With