-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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(TS): allow CSSObject on @emotion/styled #1129
Conversation
Hmmm... Just noticed this test: emotion/packages/styled-base/types/tests.tsx Lines 39 to 41 in 6f3ee3f
I'm not sure how that's working because using the object syntax isn't working for me. I'm using |
The failure is:
I'm not sure how to fix that 😬 |
styled.button and stuff should be in the @emotion/styled package |
Ok, so I fixed the test, but then I added a few more tests for things that I think should be errors but they're not and I'm not sure why... |
@kentcdodds We cannot emit an error on "wrong properties", since we should handle something like |
@@ -72,7 +71,7 @@ export interface CreateStyledComponentBase< | |||
ReactClassPropKeys | |||
> = Omit<InnerProps & ExtraProps, ReactClassPropKeys> | |||
>( | |||
template: TemplateStringsArray, | |||
template: TemplateStringsArray | CSSObject, |
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.
This case is covered by the previous overloading, so you don't need to add one.
Interpolation<WithTheme<StyleProps, Theme>>
is a (structural) supertype of CSSObject
.
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.
Hmmm... I wonder why I was seeing issues then. I'll dig a little more. Thank you!
Ah, I think this is the issue I was having that lead me to open this PR. Would you like me to make a new issue? This is a weird issue and I don't know what's going on. Help appreciated! Here's the code: import styled from '@emotion/styled'
const WorkingDivider = styled.hr({borderTopStyle: 'solid'})
const baseStyles = {borderTopStyle: 'solid'}
const NotWorkingDivider = styled.hr(baseStyles)
const otherBaseStyles = {margin: 20}
const AnotherWorkingDivider = styled.hr(otherBaseStyles)
export {WorkingDivider, NotWorkingDivider, AnotherWorkingDivider} Here's the error I'm getting:
So from my observations, when I specify |
I think the issue you met is #1025. Please check my comments on the issue. |
@kentcdodds @Ailrun is correct, this is due to the inner-workings of TS (and exacerbated by an error messaging issue). Although, to be fair, I think #1025 makes is hard for some TypeScript users to decipher. Let me try to explain this phenomenon because when I tripped up on this last time it was kind of hard to find a solution online. Hopefully this helps anyone else out: ExplanationThe difference in the working/non-working examples above is that // parameter type is effectively { borderTopStyle: 'solid' }
// important here: value is a string literal type
const WorkingDivider = styled.hr({borderTopStyle: 'solid'}) vs. // Notice the difference!
// type is { borderTopStyle: string }
// important here: value is a regular string type
const baseStyles = {borderTopStyle: 'solid'}
const NotWorkingDivider = styled.hr(baseStyles) while in this case, we have an object literal assigned to a variable and then passed as a function argument. Finally, the last part of your example works because // type here is { margin: number } which is totally fine
const otherBaseStyles = {margin: 20}
const AnotherWorkingDivider = styled.hr(otherBaseStyles) SolutionsThis is my favorite way to fix it. Do the type inference via annotation: import styled, { CSSObject } from '@emotion/styled';
// You could annotate the type to prevent widening
const baseStyles: CSSObject = { borderTopStyle: 'solid' } I've seen this next solution get thrown around but it's difficult to maintain. i.e. What if you need to change from // Prevent type-widening with an assertion
// ...but if you had multiple properties that needed this, it could get tedious
const baseStyles = { borderTopStyle: 'solid' as 'solid' } Other reading
|
@lychyi thanks for the explanation! I've learned something today because of your comment ❤️ |
@lychyi Thank you for such detailed explanation! |
@lychyi Oh, and in your solution, |
This has been super helpful. Thank you friends! |
@Ailrun Good to know! Thanks for the heads up. |
What: This allows:
styled.div(/* this can be an object /*)
Why: Because that API is supported so the typings should allow for it.
How: Tried it locally and it typed fine (even helped me fix an issue I had), so I just made this change in the github editor.
Checklist: