Description
TypeScript Version: 3.2.2 and 3.3.0-dev.20190111
Search Terms: function return, function return type, function return not type checking
Code
I'm writing a type-safe React CSS-in-JS library called Aesthetic. For the most part, the library is complete and works great. The biggest issue is that TS is not type checking correctly on the consumer side. Before I dig into an example, a little background on the type system.
Aesthetic defines a handful of types (based on csstype) to structure what the "CSS object" can look like. This includes properties, attribute selectors, pseudo selectors, at-rules, and other nested values. These can all be seen here: https://github.com/milesj/aesthetic/blob/master/packages/core/src/types.ts#L40
Styles are defined for React components using an HOC approach, by calling a function on the Aesthetic instance: aesthetic.withStyles()(Component)
. The first argument to withStyles
is a function that returns the "CSS object" or null to represent "no styles but give me the theme object".
The HOC factory is defined here: https://github.com/milesj/aesthetic/blob/master/packages/core/src/Aesthetic.tsx#L271
The style function type is defined here: https://github.com/milesj/aesthetic/blob/master/packages/core/src/types.ts#L78
An example of this in action:
function Button({ children, styles }: Props & WithStylesProps) {
return (
<button type="button" className={classes(styles.button)}>
{children}
</button>
);
}
export default withStyles(({ unit }) => ({
button: {
textAlign: 'center',
display: 'inline-block',
padding: unit,
},
}))(Button);
The issue is the function's returned object in the withStyles
1st argument is not being type checked, so all usability and development experience is thrown out the window right now. I put together a test case showing this behavior: https://github.com/milesj/aesthetic/blob/master/packages/core/tests/properties.tsx
And a few screenshots showing the behavior in VS code.
When using objects directly (not as a function return), the invalid properties are correctly highlighted.
When using a function, the invalid properties are not highlighted.
What's even more confusing is the VS code tooltips display the correct type for the argument, StyleSheetDefinition
.
I've also tried removing the null
union from StyleSheetDefinition
, export type StyleSheetDefinition<Theme, Props = any> = (theme: Theme, props: Props) => StyleSheet;
, but the same problem still persists.
Expected behavior:
Objects returned in a function are typed according to their contract.
Actual behavior:
Objects returned in a function are not being typed.
Related Issues: Couldn't find any applicable.