How can JSDoc be used to type props of styled-components in combination with tsconfig.json and tsc
.
In TypeScript this is very easy with a simple generic, unfortunately I cannot achieve the same using JSDoc. I would imagine doing something like this.
/** @type {import('styled-components').styled["div"]<{ $open: boolean }>} */
const ChildContent = styled.div`
animation: ${p => p.$open ? slideOpen : slideClose};
`
I noticed that StyleFunction works and the props can be provided using the generic. However, this type does not include any information about the component, only the props of the component. So the code below does not show any errors, until it’s used with for instance a ref property.
/** @type {import("styled-components").StyleFunction<{ $open: boolean }>} */
const ChildContent = styled.div`
animation: ${p => p.$open ? slideOpen : slideClose};
`
// breaks here, 'ChildContent' cannot be used as a JSX component.
const Component = <ChildContent style={{ position: "absolute" }} $open={show} />
So another possible solution would be to combine this with another generic that takes the Runtime
and Target
. But, even better would be to directly access the function generic in Styled (exported as StyledInstance).
Big thanks for anyone who can help find the correct type.
2
Answers
Thanks to Jesus Jemenez Cordero I better understood the StyledInstance type. And with some type inference it is possible to create a simple type and add that to a .d.ts file.
Here are the steps I took to get to the solution: (Step 4 and 5 contain the final code)
Target
, HTMLOuterProps
andOuterStatics
are already filled in. So create a .d.ts file with that can extract these automatically.StyledComponent
type to add props to the type.Unfortunately this is an incomplete answer. The answer at least misses extending existing styled-components using the
styled(MyComponent)
syntax.Sound like your are missing a couple of properties on your tcsconfig.json. If I’m not wrong, to integrate JSDoc you need to add this props if you want to have al JSDoc working correctly.
And your component and types maybe need to look something similar to this instead: