I'm using Visual Studio Code's Type-Checking Javascript feature. For those unfamiliar, this enables inferred typing, so you get many benefits of typing in VS Code, without having to write types.
Unfortunately it has issues with the template tag-based components in the Styled Components library. If I have a component like:
const ProductImage = styled.div`
background-image: url("${props => props.imagePath}");
`;
VS Code adds a squiggly warning line, just under imagePath
(but not props.
), because Typescript can't infer the type of the props argument.
As I understand it, Typescript can also get types from JSDoc, so I tried adding:
/**
* @param {String} [props.imagePath]
* @param {String} [props.alignRight]
*/
const ProductImage = styled.div`
background-image: url("${props => props.imagePath}");
float: ${props => (props.alignRight ? `left` : `right`)}};
`;
... but it doesn't work.
I don't have a tsconfig.js
, but to enable the JSDoc typing I tried adding the following to my jsconfig.js
:
// Generate d.ts files
"declaration": true,
// This compiler run should only output d.ts files
"emitDeclarationOnly": true
... but it also didn't help.
My questions are:
Based on this guide, you need to use a generic call in order to use custom types.
In typescript it would be something like:
const Button = styled.TouchableOpacity<ButtonProps>`
opacity: ${(props) => (props.primary ? 0.5 : 1)};
`;
Unfortunately, there's no equivalent in JSDoc, but you can use a cast.
So your code would need to be something like:
const styled = require('styled-components').default;
/**
* @typedef {{
* imagePath: string;
* alignRight: boolean;
* }} ProductImageProps */
const ProductImage =
/** @type {import('styled-components').ThemedStyledFunction<'div', ProductImageProps>} */
(styled.div)`
background-image: url("${props => props.imagePath}");
float: ${props => (props.alignRight ? `left` : `right`)}};
`;
The weird looking /** @type {SomeType} */ (expression)
construct is how casts are done in JSDoc. The parentheses are required.
Note that you will need to install @types/styled-components as a dev dependency.
Note 2: I tested this using JSDoc in my local setup, however I do have a tsconfig.json file.