-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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.


