I was trying to implement a Typography react component.
As you can see below, I got variant as an input prop and used it as index of VariantsMap object to get corresponding html tag name.
Then I used styled-components 'as' polymorphic prop to render it as selected html tag.
but I keep get this error :
No overload matches this call. Overload 1 of 2, '(props: Omit<Omit<Pick<DetailedHTMLProps<HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "key" | keyof HTMLAttributes<...>> & { ...; } & { ...; }, never> & Partial<...>, "theme"> & { ...; } & { ...; }): ReactElement<...>', gave the following error. Type 'string' is not assignable to type 'undefined'.
I found in @types/styled-component that 'as' props can be 'never | undefined', and my variantsMap returns string type.
But I really want to use this 'as' prop with my variant-specific html tag selection feature.
Is there any way to solve this problem?
const variantMap = {
h1: 'h1',
h2: 'h2',
h3: 'h3',
h4: 'h4',
h5: 'h5',
h6: 'h6',
subheading1: 'h6',
subheading2: 'h6',
body1: 'p',
body2: 'p',
};
export const Typography = ({ variant : string }) => {
const selectedComponent = variantMap[variant];
return (<TypographyRoot
as={selectedComponent}
variant={variant}
{...props}
>
{children}
</TypographyRoot>);
}
CodePudding user response:
First of all, export const Typography = ({ variant : string }) => {}
is invalid syntax.
You just changed the name of destructured variant
to string
. You did not provide a type.
The reason you have an error even with valid string
type like here export const Typography = ({ variant }:{variant: string}) => {}
is that variantMap
expects as a key h1
| 'h2' |'h3' ... keys whereas string
is much wider.
I'd willing to bet that you don't want to assign foo
string to variant
property.
IN order to fix it, you just need to make variantMap
immutable and apply appropriate constraint to variantMap
:
import React from 'react'
import styled from "styled-components";
const Div = styled.div`
color: red;
`;
const VariantMap = {
h1: 'h1',
h2: 'h2',
h3: 'h3',
h4: 'h4',
h5: 'h5',
h6: 'h6',
subheading1: 'h6',
subheading2: 'h6',
body1: 'p',
body2: 'p',
} as const;
type Props = {
variant: keyof typeof VariantMap
}
export const Typography = ({ variant }: Props) => {
const selectedComponent = VariantMap[variant];
return <Div
as={selectedComponent}
/>
}
Now styled-component
is happy.