Conversation
|
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 5e104f2:
|
packages/react/types/index.d.ts
Outdated
| type ReactArrayInterpolation<Props> = Array<ReactInterpolation<Props>> | ||
|
|
||
| interface ReactFunctionInterpolation<Props> { | ||
| (props: Props): ReactInterpolation<Props> | ||
| } | ||
|
|
||
| export type ReactInterpolation<Props> = | ||
| | ReactInterpolationPrimitive | ||
| | ReactArrayInterpolation<Props> | ||
| | ReactFunctionInterpolation<Props> | ||
|
|
There was a problem hiding this comment.
Can we call the type parameter Theme since that's what it is here?
There was a problem hiding this comment.
Ive also used it for one of the styled overloads where it is equivalent to Props
There was a problem hiding this comment.
This type doesn't seem right for styled, e.g. styled.div('display:flex;') is valid.
Also, this change isn't right for the css prop either since css={['display:flex;']} is valid. The only thing that's wrong about the current types is that string isn't allowed at the root of the css prop.
There was a problem hiding this comment.
Well, sure - the question is if we want to support this. Types don't always have to match the runtime reality fully. It feels better to guide users to better patterns if they are using a type checker.
There was a problem hiding this comment.
@mitchellhamilton oh ok, I must have missed these style string patterns in the doc because I based my suggestion on what I saw demonstrated. If we really want to allow this form of string we can go ultra geeky and use template literal types but it seems overengineering at this point.
To be honest, the one thing I'm really interested in is for TS to catch me (and anyone starting with the css property) when I'm worngly assigning a class name to the css property.
So I'd agree with @Andarist here. It's about nudging and guiding to use some patterns rather that fully typing everything that could work but it's up to you folks.
There was a problem hiding this comment.
Sure, let's change this for the css prop. Can you revert the change for @emotion/styled though since having @emotion/styled depend on a new thing from @emotion/react would be a breaking change since @emotion/styled has a peer dependency on @emotion/react? (also for styled, i believe we compile styles to styled.div('display: ', something, ';') and making it so our types treat something that we compile to as invalid seems bad)
There was a problem hiding this comment.
Ok, I've removed this from @emotion/styled and also renamed Props to Theme since this will always be true right now.
This might be a user-facing change (some people might use Interpolation type in their code) but I think this is OK if we make this a minor change. Tying major versioning to types (unless changes are really extreme) falls outside of the pragmatic semver for me. What's your opinion on this?
| func: (props: Props, context: EmotionCache, ref: Ref<RefType>) => ReactNode | ||
| ): FC<Props & ClassAttributes<RefType>> | ||
|
|
||
| type ReactInterpolationPrimitive = |
There was a problem hiding this comment.
I think fundamentally what we mean is falsy or something that produce valid style information:
type ReactInterpolationPrimitive =
| Falsy
| SerializedStyles
| CSSObjectFalsy in TS can be expressed like that (note the "" and false instead of boolean):
type Falsy = false | "" | 0 | null | undefinedAny other value would be probably the result of a programming mistake and would not be interpreted correctly by Emotion anyway, so we might as well catch them:
css={"my-custom-class"}
css={true}whereas the following could be the intended result of a boolean shortcircuit conditional:
css={""}
css={false}There was a problem hiding this comment.
Hah, interesting that with someString && somethingElse TS actually computes the output as "" | typeof somethingElse! TIL
There was a problem hiding this comment.
@Andarist yes this is pretty neat. From the quick test of my code base (a branch where I'm refactoring to use the css property), these types already help me a lot in finding mistakes I made.
In your example, for res2, I expected TS to be a little smarter with the ternary operator. I can't really understand what other value foo can be in the right branch other then "" 🤷♂️..
So this case would generate a false negative, but to be fair I think this is a pattern that should be very rare when using Emotion. I can't really see what one would want to achieve with this where the shortcircuit conditional would be enough.
There was a problem hiding this comment.
In your example, for res2, I expected TS to be a little smarter with the ternary operator. I can't really understand what other value foo can be in the right branch other then "" 🤷♂️..
Yep, same - both ternary and && should really behave the same way. This was for illustration purposes - not that relevant for this PR really (I don't feel that it's a show-stopper or anything).
There was a problem hiding this comment.
FYI, after unsuccessfully trying to find the answer in TS repository, I just posted the question on SO
|
@Andarist did you need help with this? I'm quite keen to see it merged so tell me if I can do anything. |
|
@jraoult adding type tests and checking what happens with failed CI jobs (the ones on the CircleCI) would certainly help |
|
@Andarist I took some time today to work on this. I think I'm ready to push. How should I proceed? Can you give me write access to this branch? Should I create another PR? |
|
U can create a PR targeting this branch |
|
@jraoult @mitchellhamilton passing string prop is actually supported in the codebase: emotion/packages/react/src/emotion-element.js Lines 66 to 74 in 4d7efcb I guess this was mainly to make the Emotion 9 -> Emotion 10 easier but this code has not been removed in Emotion 11. This logic probably kicks in when providing the |
Exactly, this is actually what got me into this rabbit hole initially 😉 During refactoring, I noticed one could still give the So my initial proposal for this typing was to make sure no undocumented pattern could be used and help people avoid the pitfall. |
fixes #2289