Skip to content

Commit

Permalink
Fix mismatch between CSSInterpolation and Interpolation<Props> (#3164)
Browse files Browse the repository at this point in the history
* Add explicit test for uncovered regression; fix interpolation type to make it pass

* Reorder overloads for styled component creator

Formerly, the first overload to be tried was not accepting template strings array as first argument. Therefore, it couldn't be used when `styled` was used as a tag for template string. So in this case TS skipped this overload and fell through to the next.
Now, though, with `ArrayInterpolation` type changed, `TemplateStringsArray` matches the definition of `ArrayInterpolation`; therefore, this overload becomes used for template strings, confusing type inference.

This change moves this overload to the end of the list, i.e. to be used as fallback when there's actually a direct function call, without template string.

* yarn changeset

* Apply suggestions from code review

* Create tiny-snails-watch.md

---------

Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
  • Loading branch information
Cerber-Ursi and Andarist committed Mar 29, 2024
1 parent 6e0e388 commit c9b84db
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .changeset/curly-planets-search.md
@@ -0,0 +1,5 @@
---
'@emotion/serialize': patch
---

Make `ArrayInterpolation` to extend `ReadonlyArray` to match a similar recent change to `ArrayCSSInterpolation`. It fixes some compatibility issues when those 2 get mixed together.
5 changes: 5 additions & 0 deletions .changeset/tiny-snails-watch.md
@@ -0,0 +1,5 @@
---
"@emotion/styled": patch
---

Reordered `styled` overloads to accommodate the recent change in `@emotion/serialize`'s types.
4 changes: 4 additions & 0 deletions packages/react/types/tests.tsx
Expand Up @@ -9,6 +9,7 @@ import {
withEmotionCache
} from '@emotion/react'
import { JSX as EmotionJSX } from '@emotion/react/jsx-runtime'
import { CSSInterpolation } from '@emotion/serialize'

declare module '@emotion/react' {
// tslint:disable-next-line: strict-export-declare-modifiers
Expand All @@ -23,6 +24,9 @@ declare module '@emotion/react' {
;<Global styles={[]} />
;<Global styles={theme => [theme.primaryColor]} />

declare const getStyles: () => CSSInterpolation
;<Global styles={getStyles()} />

declare const getRandomColor: () => string

const ComponentWithCache = withEmotionCache((_props: {}, cache) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/serialize/types/index.d.ts
Expand Up @@ -52,7 +52,7 @@ export type Keyframes = {
} & string

export interface ArrayInterpolation<Props>
extends Array<Interpolation<Props>> {}
extends ReadonlyArray<Interpolation<Props>> {}

export interface FunctionInterpolation<Props> {
(props: Props): Interpolation<Props>
Expand Down
20 changes: 10 additions & 10 deletions packages/styled/types/base.d.ts
Expand Up @@ -63,10 +63,18 @@ export interface CreateStyledComponent<
SpecificComponentProps extends {} = {},
JSXProps extends {} = {}
> {
(
template: TemplateStringsArray,
...styles: Array<
Interpolation<ComponentProps & SpecificComponentProps & { theme: Theme }>
>
): StyledComponent<ComponentProps, SpecificComponentProps, JSXProps>

/**
* @typeparam AdditionalProps Additional props to add to your styled component
*/
<AdditionalProps extends {} = {}>(
<AdditionalProps extends {}>(
template: TemplateStringsArray,
...styles: Array<
Interpolation<
ComponentProps &
Expand All @@ -80,18 +88,10 @@ export interface CreateStyledComponent<
JSXProps
>

(
template: TemplateStringsArray,
...styles: Array<
Interpolation<ComponentProps & SpecificComponentProps & { theme: Theme }>
>
): StyledComponent<ComponentProps, SpecificComponentProps, JSXProps>

/**
* @typeparam AdditionalProps Additional props to add to your styled component
*/
<AdditionalProps extends {}>(
template: TemplateStringsArray,
<AdditionalProps extends {} = {}>(
...styles: Array<
Interpolation<
ComponentProps &
Expand Down

0 comments on commit c9b84db

Please sign in to comment.