Open mdjzon opened 4 months ago
The styled
wrapper exposes a generic that intercepts passed props in order to determine a runtime target and extract types. I don't think a generic component assembled in this fashion will work. Have you considered using the as
prop to accomplish your goal? That's the design intent of that API to switch what's being rendered without messing with styles.
Maybe my example was not comprehensive enough, or a bit misleading. The generic props in our use-cases are not related to what's being rendered by the styled component (there the as
prop would be useful, as you mentioned). I changed the codesandbox example to illustrate the same problem but in a different context where the generic prop is used for specifying the interface representing the values in a form (backed by react-hook-form). Hope this is more clear.
But I just realised that it has actually has never worked - in v6.1.1 the type information was stripped "silently" and thus TS did not complain. The recent changes in v6.1.3 only made it more obvious by producing an actual TS error.
So if it is not possible for you to solve (allowing styled generic components) I'll just have to find a different solution. This issue can be closed in that case..
Just another thought, you could provide an untyped initial component and then retype it using as
. e.g.
<StyledField as={Field<FormValues>} name="value2" label="Value 2" />
It's equivalent to your sandbox but types properly since it doesn't try to override the styled()
wrapper generic.
I have this issue as well. Casting using as
is an option. Another option is to declare the type explicitly, e.g. from mdjzon's Codesandbox:
const StyledField: typeof Field = styled(Field)`
color: deeppink;
`;
@mdjzon If you have a static type (FormValues) you can set it inside the styled function with the component:
const StyledField = styled(Field<FormValues>)
color: deeppink;
;
We used to use satisfies
and 6.1.8 breaks it for us. Same typescript error about WebTarget
.
const Comp = <T,>(props: {
className?: string,
onOpen:(item: T) => void,
items: T[]
}): JSX.Element | null => {
return <div className={props.className}>{/* implementation */}</div>;
}
cons StyledComp = styled(Comp)`` satisfies typeof Comp;
This is during upgrading 6.1.0 to 6.1.8.
This is a workaround that keeps the generic correctly but I'd love not to have to do this. It looks like this is becase styled(fn)
itself gained a generic.
type StyledComponent = Styled<'web', any, any, any>;
const StyledComboboxMenu = styled(ComboboxMenu)`
width: 340px;
` satisfies StyledComponent & typeof ComboboxMenu;
Workaround iteration 2 with no any
.
type StyledComponent = Styled<
'web',
WebTarget,
Record<never, never>,
Record<never, never>
>;
const StyledComboboxMenu = styled(ComboboxMenu)`
width: 340px;
` satisfies StyledComponent & typeof ComboboxMenu;
Happy to make a new issue if you don't feel like this is the same, but I have a similar issue with components not having generics respected correctly so their props are not correctly defined:
Reproduction
Steps to reproduce
https://codesandbox.io/p/sandbox/wizardly-kapitsa-nxcwtz?file=%2Fsrc%2FApp.tsx%3A22%2C39
Expected Behavior
No TS errors.
Actual Behavior
Using a styled generic component results in the following TS error:
This started to happen in v6.1.3. Still a problem in v6.1.6. Works fine in v6.1.1.
Possibly related to this PR: https://github.com/styled-components/styled-components/pull/4236