New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: refactor styled-base Flow types to work again #1570
Conversation
🦋 Changeset is good to goLatest commit: ff63490 We got this. Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
9f9fa89
to
2fecf15
Compare
Codecov Report
|
What do you mean by "part of the work needed to fix #1515"? What has to be done to consider that ticket done other than this PR? |
I still got “any” out from the styled package, but maybe it’s just some local issue with the monorepo |
Could you try building & linking packages to your repro case? That way you could check how this would behave if this would get published |
I updated the types, now StyledComponent is a polymorphic type (like React$StatelessFunctionalComponent) so that you can use it as follows: type Props = { color: string };
const Foo = styled<Props>`
color: ${props => props.color};
`; This has the advantage that it makes it easy to catch errors inside your styled components, but has the disadvantage of requiring the type in all cases. I would like to make it optional, so that it fallbacks to |
packages/styled-base/src/utils.js
Outdated
} | ||
|
||
export type StyledComponent<P> = React$StatelessFunctionalComponent<P> & { | ||
defaultProps: P, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this correct? shouldnt Partial<P>
equivalent from flow be used here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah probably this should be $Shape<P>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't unable to use $Shape<P>
because that would then get assigned to P
and throw a type error.
It looks like Flow doesn't support defaultProps
, I typed it as any
for now :-(
Isn't requiring type at all times (as its hard to infer it) better than falling back to any? |
Yes it's absolutely better, but it's kind of a breaking change, because now all the untyped styled components will require the annotation. Also, if I don't expect to assign any property to my styled component and I plan to use it only internally of some larger component I may not want to define a type for each of them, like it happens when I define a internal component I should have probably said that I'd like it to fallback to inference, rather than to |
7b06bff
to
ee69409
Compare
I guess I hit a road blocker... Flow doesn't seem to support type parameters on tagged template strings 😢 So that means we aren't able to do:
We could still merge this PR if we at least found a way to make But without this, the tagged template usage is completely unusable. |
f8d31ba
to
2f99e63
Compare
@FezVrasta let me know when you are done with this PR - I'll do a code review then and we'll be able to merge this in |
I don't understand why if I write the following code in
|
Oh damn it, Flow is right... The test fails because I'm trying to export |
Ok @Andarist I think we are ready for a final review. Notable unresolved/unaddressed issues:
Breaking changes (?):
*: I'm not sure we should consider this a breaking change, is more like a fix for something that wasn't working properly but should never have been allowed in first place. |
fa563f2
to
086bd8b
Compare
@FezVrasta thanks! |
So, this change has caused our flow error count to jump up to around 800 after getting this version bump in our project. Any suggestions for how to adopt this type of change in a large project. We're also using |
@bradringel could you reduce your failing call sites to small repro cases? when fixing those we could include them as "flow tests". |
@Andarist sure. A super basic one like this fails:
typing the component with
doesn't have an error |
Isn't the problem here that previously such component had "props" typed to |
That's true, it was implicitly unsafe, but now we need to go and fix 800 of these types of errors. And because flow doesn't support generics for tagged template literals, which is how a lot of those components are written, they're all just going to get typed to This is technically a safer way to write those components, but is a big change to the way we need to interact with this library, and was introduced in a patch version. |
Let me preface this by saying we are fans of Emotion - we use it all over our project. So, please don't take this as an attack, I'm just looking for advice for suggested usage in Flow situations. I could be missing something really easy (it wouldn't be the first or last time), but it feels like Flow users are in for a wild time if no version of tagged templates is supported. Is your position that we should be doing this instead?
Our whole project uses both of the tagged template forms below (I realize, unsafe), and both do not pass flow checks if I try to type the 'styled' call with a generic. We export them because we like to separate all of our styled components which form our 'building blocks' from the complex components that use them instead of lumping them together in the same file. Using the tagged template versions of these calls let us write css-like implementations instead of JSON-like structures, which was also really appealing:
I feel like the answer, "yes, you can use tagged template forms of the calls but you will be forced to type them all to keep Flow from complaining" is a lot different than "you can't use this supported feature even if you type it unless you want to live with Flow complaining until they support tagged templates". The former is a lot less work than the latter, even if both are time consuming to some degree in a large project. That's where I agree with @bradringel that this feels like a major change, not a minor version bump. I think I'll wait to hear what you suggest and pin to the previous version in the meantime. Based on the answer, we'll plan to make these changes as part of tech debt after our release deadline is met. Thanks for taking the time to read and respond. I do not imagine being a maintainer of a popular OSS project is easy - much respect. |
I made some further improvements to the Flow types in this PR #1588 It’s currently in the next branch. I’m from mobile but once I get back on my computer I’ll try to provide a more complete answer |
I see that on the emotion/packages/styled/flow-tests/index.js Lines 18 to 20 in 923ded0
So you should be able to work around Flow not accepting generics on tagged template calls. I'm not sure if this supported with types on master though, could you check this for me?
I understand the inconvenience caused by this and I'm truly sorry for that. I believe that it's not practical to tie types to semver closely though (when it makes sense to use we try to do that though, in example we've pushed TS types refactoring to
If those were previously unsafe and typed to any I could help you writing a codemod that would just make those explicit in your code. |
* fix: refactor styled-base Flow types to work again * fix: improve Styled type to accept optional props type * fix: make styled package return proper types * fix: missing flow header * test: test untyped styled component * chore: fix site types * docs: comment typo
What:
work needed to fix #1515
Why:
right now styled components are typed as
any
How:
refactored the Flow types of styled-base to make sure they return the proper types
Checklist: