From 07a70a474105c5887c46992287b6540fc4130c5e Mon Sep 17 00:00:00 2001 From: Toms Seisums Date: Tue, 5 Nov 2019 22:24:00 +0200 Subject: [PATCH 01/18] Updated types to support global Theme definition --- packages/core/types/index.d.ts | 13 +++++++++---- packages/core/types/theming.d.ts | 15 ++++++++++++--- packages/styled/types/base.d.ts | 3 ++- packages/styled/types/index.d.ts | 5 +++-- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts index bb821e8d2..7b1aded57 100644 --- a/packages/core/types/index.d.ts +++ b/packages/core/types/index.d.ts @@ -64,7 +64,7 @@ export interface GlobalProps { * @desc * JSX generic are supported only after TS@2.9 */ -export function Global( +export function Global( props: GlobalProps ): ReactElement @@ -96,17 +96,22 @@ export interface ClassNamesProps { * @desc * JSX generic are supported only after TS@2.9 */ -export function ClassNames( +export function ClassNames( props: ClassNamesProps ): ReactElement declare module 'react' { interface DOMAttributes { - css?: InterpolationWithTheme + css?: InterpolationWithTheme } } declare global { + namespace Emotion { + // tslint:disable-next-line: no-empty-interface strict-export-declare-modifiers + export interface Theme {} + } + namespace JSX { /** * Do we need to modify `LibraryManagedAttributes` too, @@ -114,7 +119,7 @@ declare global { */ interface IntrinsicAttributes { - css?: InterpolationWithTheme + css?: InterpolationWithTheme } } } diff --git a/packages/core/types/theming.d.ts b/packages/core/types/theming.d.ts index 87766f642..a001eda2e 100644 --- a/packages/core/types/theming.d.ts +++ b/packages/core/types/theming.d.ts @@ -2,20 +2,29 @@ // TypeScript Version: 3.1 import * as React from 'react' +import '@emotion/core' import { DistributiveOmit, PropsOf } from './helper' +import { + StyledComponent, + StyledOptions, + CreateStyledComponent, + StyledTags +} from '@emotion/styled' export interface ThemeProviderProps { theme: Partial | ((outerTheme: Theme) => Theme) children?: React.ReactNode } -export interface ThemeProvider { +export interface ThemeProvider { (props: ThemeProviderProps): React.ReactElement } -export type useTheme = () => T +export type useTheme = < + T extends Theme = Theme +>() => T -export type withTheme = < +export type withTheme = < C extends React.ComponentType> >( component: C diff --git a/packages/styled/types/base.d.ts b/packages/styled/types/base.d.ts index 92fe808fb..dc6762903 100644 --- a/packages/styled/types/base.d.ts +++ b/packages/styled/types/base.d.ts @@ -13,6 +13,7 @@ */ import * as React from 'react' +import '@emotion/core' import { ComponentSelector, Interpolation } from '@emotion/serialize' import { PropsOf, DistributiveOmit } from '@emotion/core' @@ -99,7 +100,7 @@ export interface CreateStyledComponent< * @example styled('div')({ width: 100 }) * @example styled('div')(props => ({ width: props.width }) */ -export interface CreateStyled { +export interface CreateStyled { < C extends React.ComponentType>, ForwardedProps extends keyof React.ComponentProps< diff --git a/packages/styled/types/index.d.ts b/packages/styled/types/index.d.ts index 6e3cf4842..b9a060b3e 100644 --- a/packages/styled/types/index.d.ts +++ b/packages/styled/types/index.d.ts @@ -1,6 +1,7 @@ // Definitions by: Junyoung Clare Jang // TypeScript Version: 3.2 +import '@emotion/core' import { CreateStyled as BaseCreateStyled, CreateStyledComponent } from './base' export { @@ -15,7 +16,7 @@ export { CreateStyledComponent } from './base' -export type StyledTags = { +export type StyledTags = { [Tag in keyof JSX.IntrinsicElements]: CreateStyledComponent< { theme?: Theme }, JSX.IntrinsicElements[Tag], @@ -23,7 +24,7 @@ export type StyledTags = { > } -export interface CreateStyled +export interface CreateStyled extends BaseCreateStyled, StyledTags {} From 3ad510f90965ac527efcff6172789c4520642623 Mon Sep 17 00:00:00 2001 From: Toms Seisums Date: Tue, 5 Nov 2019 23:25:12 +0200 Subject: [PATCH 02/18] Updated documentation to reflect new theme typings --- docs/typescript.mdx | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/docs/typescript.mdx b/docs/typescript.mdx index 03042a6c9..77cd580fb 100644 --- a/docs/typescript.mdx +++ b/docs/typescript.mdx @@ -248,28 +248,30 @@ const App = () => ( ### Define a Theme By default, `props.theme` has an `any` type annotation and works without any errors. -However, you can define a theme type by creating another `styled` instance. - -_styled.tsx_ - -```tsx -import styled, { CreateStyled } from '@emotion/styled' -import { useTheme, ThemeProvider, EmotionTheming } from '@emotion/core' - -type Theme = { - color: { - primary: string - positive: string - negative: string - } - // ... +However, you can define a theme type by extending our type declarations via your own declarations file. + +_emotion.d.ts_ + +```typescript +declare global { + namespace Emotion { + export interface Theme { + colors: { + body: string + text: string + } + } + } } -export default styled as CreateStyled +// You are also able to use a 3rd party theme this way: +import { MuiTheme as MaterialUITheme } from 'material-ui' -// You can also create themed versions of all the other theme helpers and hooks -const { ThemeProvider, useTheme } = { ThemeProvider, useTheme } as EmotionTheming -export { ThemeProvider, useTheme } +delcare global { + namespace Emotion { + export interface Theme extends MaterialUITheme {} + } +} ``` _Button.tsx_ From c55d448953ff1aefc5dd0423f17bae9981f96951 Mon Sep 17 00:00:00 2001 From: Toms Seisums Date: Tue, 5 Nov 2019 23:33:12 +0200 Subject: [PATCH 03/18] Simplified MuiTheme import syntax in docs --- docs/typescript.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/typescript.mdx b/docs/typescript.mdx index 77cd580fb..e8edf2aee 100644 --- a/docs/typescript.mdx +++ b/docs/typescript.mdx @@ -265,11 +265,11 @@ declare global { } // You are also able to use a 3rd party theme this way: -import { MuiTheme as MaterialUITheme } from 'material-ui' +import { MuiTheme } from 'material-ui' delcare global { namespace Emotion { - export interface Theme extends MaterialUITheme {} + export interface Theme extends MuiTheme {} } } ``` From 7be6f6407f0a2e5d37809d3ffb0c7c69d3c1bd85 Mon Sep 17 00:00:00 2001 From: Toms Seisums Date: Tue, 5 Nov 2019 23:34:40 +0200 Subject: [PATCH 04/18] Use previous theme declaration in docs - [side-effect] Updated back to 2 space indentation --- docs/typescript.mdx | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/typescript.mdx b/docs/typescript.mdx index e8edf2aee..f5327ad07 100644 --- a/docs/typescript.mdx +++ b/docs/typescript.mdx @@ -254,23 +254,24 @@ _emotion.d.ts_ ```typescript declare global { - namespace Emotion { - export interface Theme { - colors: { - body: string - text: string - } - } + namespace Emotion { + export interface Theme { + color: { + primary: string + positive: string + negative: string + } } + } } // You are also able to use a 3rd party theme this way: import { MuiTheme } from 'material-ui' delcare global { - namespace Emotion { - export interface Theme extends MuiTheme {} - } + namespace Emotion { + export interface Theme extends MuiTheme {} + } } ``` From 353dc2efba26692935cea403032dc67ff1374e96 Mon Sep 17 00:00:00 2001 From: Toms Seisums Date: Tue, 5 Nov 2019 23:36:24 +0200 Subject: [PATCH 05/18] Update Button.tsx import declaration for styled --- docs/typescript.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/typescript.mdx b/docs/typescript.mdx index f5327ad07..50ce04fd8 100644 --- a/docs/typescript.mdx +++ b/docs/typescript.mdx @@ -278,7 +278,7 @@ delcare global { _Button.tsx_ ```tsx -import styled from '../path/to/styled' +import styled from '@emotion/styled' const Button = styled('button')` padding: 20px; From 358c12d45bc36b18f2705625badd93b5298644c6 Mon Sep 17 00:00:00 2001 From: joltmode Date: Wed, 6 Nov 2019 12:40:58 +0200 Subject: [PATCH 06/18] Updated type definitions to default to any if not defined --- packages/core/types/index.d.ts | 9 +++++---- packages/core/types/theming.d.ts | 7 ++++--- packages/styled/types/base.d.ts | 4 ++-- packages/styled/types/index.d.ts | 5 +++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts index 7b1aded57..8b5cd049c 100644 --- a/packages/core/types/index.d.ts +++ b/packages/core/types/index.d.ts @@ -38,6 +38,7 @@ export { export * from './theming' export * from './helper' +export type AnyIfEmpty = keyof T extends never ? any : T export const ThemeContext: Context export const CacheProvider: Provider @@ -64,7 +65,7 @@ export interface GlobalProps { * @desc * JSX generic are supported only after TS@2.9 */ -export function Global( +export function Global>( props: GlobalProps ): ReactElement @@ -96,13 +97,13 @@ export interface ClassNamesProps { * @desc * JSX generic are supported only after TS@2.9 */ -export function ClassNames( +export function ClassNames>( props: ClassNamesProps ): ReactElement declare module 'react' { interface DOMAttributes { - css?: InterpolationWithTheme + css?: InterpolationWithTheme> } } @@ -119,7 +120,7 @@ declare global { */ interface IntrinsicAttributes { - css?: InterpolationWithTheme + css?: InterpolationWithTheme> } } } diff --git a/packages/core/types/theming.d.ts b/packages/core/types/theming.d.ts index a001eda2e..ee9acbc4d 100644 --- a/packages/core/types/theming.d.ts +++ b/packages/core/types/theming.d.ts @@ -3,6 +3,7 @@ import * as React from 'react' import '@emotion/core' +import { AnyIfEmpty } from '@emotion/core' import { DistributiveOmit, PropsOf } from './helper' import { StyledComponent, @@ -16,15 +17,15 @@ export interface ThemeProviderProps { children?: React.ReactNode } -export interface ThemeProvider { +export interface ThemeProvider> { (props: ThemeProviderProps): React.ReactElement } -export type useTheme = < +export type useTheme> = < T extends Theme = Theme >() => T -export type withTheme = < +export type withTheme> = < C extends React.ComponentType> >( component: C diff --git a/packages/styled/types/base.d.ts b/packages/styled/types/base.d.ts index dc6762903..2fda4d160 100644 --- a/packages/styled/types/base.d.ts +++ b/packages/styled/types/base.d.ts @@ -13,7 +13,7 @@ */ import * as React from 'react' -import '@emotion/core' +import { AnyIfEmpty } from '@emotion/core' import { ComponentSelector, Interpolation } from '@emotion/serialize' import { PropsOf, DistributiveOmit } from '@emotion/core' @@ -100,7 +100,7 @@ export interface CreateStyledComponent< * @example styled('div')({ width: 100 }) * @example styled('div')(props => ({ width: props.width }) */ -export interface CreateStyled { +export interface CreateStyled> { < C extends React.ComponentType>, ForwardedProps extends keyof React.ComponentProps< diff --git a/packages/styled/types/index.d.ts b/packages/styled/types/index.d.ts index b9a060b3e..cca52f928 100644 --- a/packages/styled/types/index.d.ts +++ b/packages/styled/types/index.d.ts @@ -3,6 +3,7 @@ import '@emotion/core' import { CreateStyled as BaseCreateStyled, CreateStyledComponent } from './base' +import { AnyIfEmpty } from '@emotion/core' export { ArrayInterpolation, @@ -16,7 +17,7 @@ export { CreateStyledComponent } from './base' -export type StyledTags = { +export type StyledTags> = { [Tag in keyof JSX.IntrinsicElements]: CreateStyledComponent< { theme?: Theme }, JSX.IntrinsicElements[Tag], @@ -24,7 +25,7 @@ export type StyledTags = { > } -export interface CreateStyled +export interface CreateStyled> extends BaseCreateStyled, StyledTags {} From 23717d41320808d46fe0c560a45122bbf09b4e14 Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 11 Nov 2019 10:16:22 +0800 Subject: [PATCH 07/18] Quick pass at removing theme generic param --- packages/core/types/index.d.ts | 26 ++++------ packages/core/types/tests-theming.tsx | 75 +++++++-------------------- packages/core/types/tests.tsx | 19 ++++--- packages/core/types/theming.d.ts | 27 +++------- packages/serialize/types/index.d.ts | 31 +++++++---- packages/serialize/types/tests.ts | 4 +- packages/styled/types/base.d.ts | 30 +++++++---- packages/styled/types/index.d.ts | 11 ++-- 8 files changed, 93 insertions(+), 130 deletions(-) diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts index 8b5cd049c..9f780c143 100644 --- a/packages/core/types/index.d.ts +++ b/packages/core/types/index.d.ts @@ -38,7 +38,6 @@ export { export * from './theming' export * from './helper' -export type AnyIfEmpty = keyof T extends never ? any : T export const ThemeContext: Context export const CacheProvider: Provider @@ -58,16 +57,15 @@ export type InterpolationWithTheme = | Interpolation | ((theme: Theme) => Interpolation) -export interface GlobalProps { - styles: InterpolationWithTheme +export interface GlobalProps { + styles: Interpolation } + /** * @desc * JSX generic are supported only after TS@2.9 */ -export function Global>( - props: GlobalProps -): ReactElement +export function Global(props: GlobalProps): ReactElement export function keyframes( template: TemplateStringsArray, @@ -84,26 +82,24 @@ export type ClassNamesArg = | { [className: string]: boolean | null | undefined } | ArrayClassNamesArg -export interface ClassNamesContent { +export interface ClassNamesContent { css(template: TemplateStringsArray, ...args: Array): string css(...args: Array): string cx(...args: Array): string - theme: Theme + theme: Emotion.Theme } -export interface ClassNamesProps { - children(content: ClassNamesContent): ReactNode +export interface ClassNamesProps { + children(content: ClassNamesContent): ReactNode } /** * @desc * JSX generic are supported only after TS@2.9 */ -export function ClassNames>( - props: ClassNamesProps -): ReactElement +export function ClassNames(props: ClassNamesProps): ReactElement declare module 'react' { interface DOMAttributes { - css?: InterpolationWithTheme> + css?: Interpolation } } @@ -120,7 +116,7 @@ declare global { */ interface IntrinsicAttributes { - css?: InterpolationWithTheme> + css?: Interpolation } } } diff --git a/packages/core/types/tests-theming.tsx b/packages/core/types/tests-theming.tsx index d43588cef..0e0f86509 100644 --- a/packages/core/types/tests-theming.tsx +++ b/packages/core/types/tests-theming.tsx @@ -12,22 +12,29 @@ import { import styled, { CreateStyled } from '@emotion/styled' import { Interpolation, ObjectInterpolation } from '@emotion/styled/base' -interface Theme { - primary: string - secondary: string +declare global { + namespace Emotion { + interface Theme { + primary: string + secondary: string + } + } } -declare const theme: Theme + +declare const theme: Emotion.Theme interface Props { prop: boolean } declare const CompFC: React.FC -declare class CompC extends React.Component {} +declare class CompC extends React.Component {} const WrappedCompC = withTheme(CompC) ;{WrappedCompC} ; theme} /> -; ({ ...outerTheme, ...theme })} /> +; ({ ...outerTheme, ...theme })} +/> const ThemedFC = withTheme(CompFC) ; @@ -47,9 +54,7 @@ class CompCWithDefault extends React.Component { } { - const theme: Theme = useTheme() - - const themeFail: Theme = useTheme() // $ExpectError + const theme: Emotion.Theme = useTheme() } const ThemedFCWithDefault = withTheme(CompFCWithDefault) @@ -60,23 +65,6 @@ const ThemedCompWithDefault = withTheme(CompCWithDefault) ; ; -const { ThemeProvider: TypedThemeProvider, withTheme: typedWithTheme } = { - ThemeProvider, - withTheme -} as EmotionTheming -; -// $ExpectError -; - -typedWithTheme(CompFC) - -/** - * @todo - * Following line should report an error. - */ - -typedWithTheme((props: { value: number }) => null) - { interface Book { kind: 'book' @@ -102,34 +90,12 @@ typedWithTheme((props: { value: number }) => null) ; ; ; // $ExpectError - ; // $ExpectError } -const themedStyled = styled as CreateStyled - -const StyledCompC = themedStyled(WrappedCompC)({}) -const AdditionallyStyledCompC = themedStyled(StyledCompC)({}) -; -; - -const StyledDiv = themedStyled('div')({}) -; -// $ExpectError -; -const AdditionallyStyledDiv = themedStyled(StyledDiv)({}) -; -// $ExpectError -; - -const StyledDiv2 = themedStyled.div({}) -; -// $ExpectError -; - -export type StyleDefinition = Interpolation> -export type ObjectStyleDefinition = ObjectInterpolation< - WithTheme -> +export type StyleDefinition = Interpolation +export type ObjectStyleDefinition = ObjectInterpolation<{ + theme: Emotion.Theme +}> const style: StyleDefinition = ({ theme }) => ({ color: theme.primary @@ -139,7 +105,4 @@ const style2: ObjectStyleDefinition = { } // Can use ThemeProvider -; -; -// $ExpectError -; +; diff --git a/packages/core/types/tests.tsx b/packages/core/types/tests.tsx index da5543284..c6db72be3 100644 --- a/packages/core/types/tests.tsx +++ b/packages/core/types/tests.tsx @@ -11,11 +11,16 @@ import { } from '@emotion/core' ; -interface TestTheme0 { - resetStyle: any +declare global { + namespace Emotion { + interface Theme { + primaryColor: string + secondaryColor: string + } + } } -; [theme.resetStyle]} /> +; [theme.primaryColor]} /> declare const getRandomColor: () => string @@ -92,14 +97,8 @@ const anim1 = keyframes` }} world="of-world" /> - -interface TestTheme1 { - primaryColor: string - secondaryColor: string -} - ; - {({ css, cx, theme }: ClassNamesContent) => { + {({ css, cx, theme }) => { return (
diff --git a/packages/core/types/theming.d.ts b/packages/core/types/theming.d.ts index ee9acbc4d..a180fccf3 100644 --- a/packages/core/types/theming.d.ts +++ b/packages/core/types/theming.d.ts @@ -3,7 +3,6 @@ import * as React from 'react' import '@emotion/core' -import { AnyIfEmpty } from '@emotion/core' import { DistributiveOmit, PropsOf } from './helper' import { StyledComponent, @@ -12,37 +11,27 @@ import { StyledTags } from '@emotion/styled' -export interface ThemeProviderProps { - theme: Partial | ((outerTheme: Theme) => Theme) +export interface ThemeProviderProps { + theme: Partial | ((outerTheme: Emotion.Theme) => Emotion.Theme) children?: React.ReactNode } -export interface ThemeProvider> { - (props: ThemeProviderProps): React.ReactElement +export interface ThemeProvider { + (props: ThemeProviderProps): React.ReactElement } -export type useTheme> = < - T extends Theme = Theme ->() => T - -export type withTheme> = < +export type withTheme = < C extends React.ComponentType> >( component: C -) => React.FC, 'theme'> & { theme?: Theme }> +) => React.FC, 'theme'> & { theme?: Emotion.Theme }> -export const ThemeProvider: ThemeProvider +export function useTheme(): Emotion.Theme -export const useTheme: useTheme +export const ThemeProvider: ThemeProvider export const withTheme: withTheme -export interface EmotionTheming { - ThemeProvider: ThemeProvider - useTheme: useTheme - withTheme: withTheme -} - export type WithTheme = P extends { theme: infer Theme } ? P & { theme: Exclude } : P & { theme: T } diff --git a/packages/serialize/types/index.d.ts b/packages/serialize/types/index.d.ts index 606bb7545..252c63eb1 100644 --- a/packages/serialize/types/index.d.ts +++ b/packages/serialize/types/index.d.ts @@ -15,8 +15,12 @@ export type CSSPropertiesWithMultiValues = { /** * @desc Following type exists for autocompletion of key. */ -export type CSSPseudos = { [K in CSS.Pseudos]?: ObjectInterpolation } -export interface CSSOthersObject { +export type CSSPseudos< + MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } +> = { [K in CSS.Pseudos]?: ObjectInterpolation } +export interface CSSOthersObject< + MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } +> { [propertiesName: string]: Interpolation } @@ -56,17 +60,22 @@ export type Keyframes = { toString: () => string } & string -export interface ArrayInterpolation extends Array> {} -export interface ObjectInterpolation - extends CSSPropertiesWithMultiValues, - CSSPseudos, - CSSOthersObject {} +export interface ArrayInterpolation< + MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } +> extends Array> {} +export interface ObjectInterpolation< + MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } +> extends CSSPropertiesWithMultiValues, CSSPseudos, CSSOthersObject {} -export interface FunctionInterpolation { +export interface FunctionInterpolation< + MergedProps extends { theme: Emotion.Theme } = { theme: Emotion.Theme } +> { (mergedProps: MergedProps): Interpolation } -export type Interpolation = +export type Interpolation< + MergedProps extends { theme: Emotion.Theme } = { theme: Emotion.Theme } +> = | null | undefined | boolean @@ -79,7 +88,9 @@ export type Interpolation = | ObjectInterpolation | FunctionInterpolation -export function serializeStyles( +export function serializeStyles< + MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } +>( args: Array>, registered: RegisteredCache, mergedProps?: MP diff --git a/packages/serialize/types/tests.ts b/packages/serialize/types/tests.ts index bb4df5872..f2f1ae30f 100644 --- a/packages/serialize/types/tests.ts +++ b/packages/serialize/types/tests.ts @@ -8,10 +8,10 @@ import { declare const testTemplateStringsArray: TemplateStringsArray declare const testKeyframes: Keyframes -const testObjectInterpolation0: ObjectInterpolation = { +const testObjectInterpolation0: ObjectInterpolation = { animation: testKeyframes } -const testObjectInterpolation1: ObjectInterpolation = { +const testObjectInterpolation1: ObjectInterpolation = { animationName: testKeyframes } diff --git a/packages/styled/types/base.d.ts b/packages/styled/types/base.d.ts index 2fda4d160..a3da95783 100644 --- a/packages/styled/types/base.d.ts +++ b/packages/styled/types/base.d.ts @@ -13,7 +13,6 @@ */ import * as React from 'react' -import { AnyIfEmpty } from '@emotion/core' import { ComponentSelector, Interpolation } from '@emotion/serialize' import { PropsOf, DistributiveOmit } from '@emotion/core' @@ -74,7 +73,10 @@ export interface CreateStyledComponent< ( ...styles: Array< Interpolation< - ComponentProps & SpecificComponentProps & StyleProps & AdditionalProps + ComponentProps & + SpecificComponentProps & + StyleProps & + AdditionalProps & { theme: Emotion.Theme } > > ): StyledComponent @@ -85,7 +87,9 @@ export interface CreateStyledComponent< template: TemplateStringsArray, ...styles: Array< Interpolation< - ComponentProps & SpecificComponentProps & AdditionalProps & StyleProps + ComponentProps & + SpecificComponentProps & + AdditionalProps & { theme: Emotion.Theme } > > ): StyledComponent @@ -100,7 +104,7 @@ export interface CreateStyledComponent< * @example styled('div')({ width: 100 }) * @example styled('div')(props => ({ width: props.width }) */ -export interface CreateStyled> { +export interface CreateStyled { < C extends React.ComponentType>, ForwardedProps extends keyof React.ComponentProps< @@ -110,15 +114,19 @@ export interface CreateStyled> { component: C, options: FilteringStyledOptions, ForwardedProps> ): CreateStyledComponent< - Pick, ForwardedProps> & { theme?: Theme }, + Pick, ForwardedProps> & { theme?: Emotion.Theme }, {}, - { theme: Theme } + { theme: Emotion.Theme } > >>( component: C, options?: StyledOptions> - ): CreateStyledComponent & { theme?: Theme }, {}, { theme: Theme }> + ): CreateStyledComponent< + PropsOf & { theme?: Emotion.Theme }, + {}, + { theme: Emotion.Theme } + > < Tag extends keyof JSX.IntrinsicElements, @@ -127,18 +135,18 @@ export interface CreateStyled> { tag: Tag, options: FilteringStyledOptions ): CreateStyledComponent< - { theme?: Theme }, + { theme?: Emotion.Theme }, Pick, - { theme: Theme } + { theme: Emotion.Theme } > ( tag: Tag, options?: StyledOptions ): CreateStyledComponent< - { theme?: Theme }, + { theme?: Emotion.Theme }, JSX.IntrinsicElements[Tag], - { theme: Theme } + { theme: Emotion.Theme } > } diff --git a/packages/styled/types/index.d.ts b/packages/styled/types/index.d.ts index cca52f928..bf1e91571 100644 --- a/packages/styled/types/index.d.ts +++ b/packages/styled/types/index.d.ts @@ -3,7 +3,6 @@ import '@emotion/core' import { CreateStyled as BaseCreateStyled, CreateStyledComponent } from './base' -import { AnyIfEmpty } from '@emotion/core' export { ArrayInterpolation, @@ -17,17 +16,15 @@ export { CreateStyledComponent } from './base' -export type StyledTags> = { +export type StyledTags = { [Tag in keyof JSX.IntrinsicElements]: CreateStyledComponent< - { theme?: Theme }, + { theme?: Emotion.Theme }, JSX.IntrinsicElements[Tag], - { theme: Theme } + { theme: Emotion.Theme } > } -export interface CreateStyled> - extends BaseCreateStyled, - StyledTags {} +export interface CreateStyled extends BaseCreateStyled, StyledTags {} declare const styled: CreateStyled export default styled From 36ea5eeb459e627936821d6aee2a5ebf5e29b2ea Mon Sep 17 00:00:00 2001 From: Jake Ginnivan Date: Mon, 11 Nov 2019 19:04:50 +0800 Subject: [PATCH 08/18] Fixed issue with Global --- packages/core/types/index.d.ts | 2 +- packages/core/types/tests.tsx | 2 +- packages/serialize/types/index.d.ts | 34 +++++++++++------------------ 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts index 9f780c143..91f09a1b1 100644 --- a/packages/core/types/index.d.ts +++ b/packages/core/types/index.d.ts @@ -58,7 +58,7 @@ export type InterpolationWithTheme = | ((theme: Theme) => Interpolation) export interface GlobalProps { - styles: Interpolation + styles: Interpolation } /** diff --git a/packages/core/types/tests.tsx b/packages/core/types/tests.tsx index c6db72be3..f18a10adc 100644 --- a/packages/core/types/tests.tsx +++ b/packages/core/types/tests.tsx @@ -20,7 +20,7 @@ declare global { } } -; [theme.primaryColor]} /> +; [theme.primaryColor]} /> declare const getRandomColor: () => string diff --git a/packages/serialize/types/index.d.ts b/packages/serialize/types/index.d.ts index 252c63eb1..95d5f0f86 100644 --- a/packages/serialize/types/index.d.ts +++ b/packages/serialize/types/index.d.ts @@ -15,12 +15,10 @@ export type CSSPropertiesWithMultiValues = { /** * @desc Following type exists for autocompletion of key. */ -export type CSSPseudos< - MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } -> = { [K in CSS.Pseudos]?: ObjectInterpolation } -export interface CSSOthersObject< - MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } -> { +export type CSSPseudos = { + [K in CSS.Pseudos]?: ObjectInterpolation +} +export interface CSSOthersObject { [propertiesName: string]: Interpolation } @@ -60,22 +58,18 @@ export type Keyframes = { toString: () => string } & string -export interface ArrayInterpolation< - MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } -> extends Array> {} -export interface ObjectInterpolation< - MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } -> extends CSSPropertiesWithMultiValues, CSSPseudos, CSSOthersObject {} +export interface ArrayInterpolation + extends Array> {} +export interface ObjectInterpolation + extends CSSPropertiesWithMultiValues, + CSSPseudos, + CSSOthersObject {} -export interface FunctionInterpolation< - MergedProps extends { theme: Emotion.Theme } = { theme: Emotion.Theme } -> { +export interface FunctionInterpolation { (mergedProps: MergedProps): Interpolation } -export type Interpolation< - MergedProps extends { theme: Emotion.Theme } = { theme: Emotion.Theme } -> = +export type Interpolation = | null | undefined | boolean @@ -88,9 +82,7 @@ export type Interpolation< | ObjectInterpolation | FunctionInterpolation -export function serializeStyles< - MP extends { theme: Emotion.Theme } = { theme: Emotion.Theme } ->( +export function serializeStyles( args: Array>, registered: RegisteredCache, mergedProps?: MP From 1c0d7c35efff7df76c52ce431874cf0dd8bed9d3 Mon Sep 17 00:00:00 2001 From: joltmode Date: Sat, 23 Nov 2019 23:30:35 +0200 Subject: [PATCH 09/18] Fixed most of the test issues - Added TODO for one possible issue --- packages/core/types/tests-theming.tsx | 9 +------- packages/serialize/types/index.d.ts | 1 + packages/styled/types/tests-base.tsx | 12 ++++++++++ packages/styled/types/tests.tsx | 32 +++++++++------------------ 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/packages/core/types/tests-theming.tsx b/packages/core/types/tests-theming.tsx index 0e0f86509..2407b4dc5 100644 --- a/packages/core/types/tests-theming.tsx +++ b/packages/core/types/tests-theming.tsx @@ -2,14 +2,7 @@ // TypeScript Version: 3.1 import * as React from 'react' -import { - useTheme, - ThemeProvider, - withTheme, - EmotionTheming, - WithTheme -} from '@emotion/core' -import styled, { CreateStyled } from '@emotion/styled' +import { useTheme, ThemeProvider, withTheme } from '@emotion/core' import { Interpolation, ObjectInterpolation } from '@emotion/styled/base' declare global { diff --git a/packages/serialize/types/index.d.ts b/packages/serialize/types/index.d.ts index 95d5f0f86..4bad424f6 100644 --- a/packages/serialize/types/index.d.ts +++ b/packages/serialize/types/index.d.ts @@ -1,6 +1,7 @@ // Definitions by: Junyoung Clare Jang // TypeScript Version: 2.8 +import '@emotion/core' import { RegisteredCache, SerializedStyles } from '@emotion/utils' import * as CSS from 'csstype' diff --git a/packages/styled/types/tests-base.tsx b/packages/styled/types/tests-base.tsx index 1f7ec293d..3c5f812cd 100644 --- a/packages/styled/types/tests-base.tsx +++ b/packages/styled/types/tests-base.tsx @@ -2,6 +2,18 @@ import * as React from 'react' import styled from '@emotion/styled/base' import isPropValid from '@emotion/is-prop-valid' +declare global { + namespace Emotion { + interface Theme { + primary: string + secondary: string + width: number + colors: { [key: string]: any } + backColor: string + } + } +} + // tslint:disable-next-line: interface-over-type-literal type ReactClassProps0 = { readonly column: boolean diff --git a/packages/styled/types/tests.tsx b/packages/styled/types/tests.tsx index 54c71f792..b1889dec8 100644 --- a/packages/styled/types/tests.tsx +++ b/packages/styled/types/tests.tsx @@ -1,19 +1,19 @@ import * as React from 'react' -import styled, { CreateStyled } from '@emotion/styled' +import styled from '@emotion/styled' -// $ExpectType CreateStyledComponent<{ theme?: any; }, DetailedHTMLProps, HTMLAnchorElement>, { theme: any; }> +// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLAnchorElement>, { theme: Theme; }> styled.a -// $ExpectType CreateStyledComponent<{ theme?: any; }, DetailedHTMLProps, HTMLBodyElement>, { theme: any; }> +// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLBodyElement>, { theme: Theme; }> styled.body -// $ExpectType CreateStyledComponent<{ theme?: any; }, DetailedHTMLProps, HTMLDivElement>, { theme: any; }> +// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLDivElement>, { theme: Theme; }> styled.div -// $ExpectType CreateStyledComponent<{ theme?: any; }, SVGProps, { theme: any; }> +// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, SVGProps, { theme: Theme; }> styled.svg { styled.div<{ bar: string }>` color: ${props => { - // $ExpectType { theme?: any; } & ClassAttributes & HTMLAttributes & { bar: string; } & { theme: any; } + // $ExpectType { theme?: Theme | undefined; } & ClassAttributes & HTMLAttributes & { bar: string; } & { theme: Theme; } props return {} @@ -24,25 +24,13 @@ styled.svg const StyledDiv = styled.div({}) ; -// can specify theme for StyledTags -const themedStyled = styled as CreateStyled<{ themeProp: string }> -const StyledDiv3 = themedStyled.div` - color: ${props => props.theme.themeProp} -` -; -const StyledDiv2 = themedStyled.div(props => { - // $ExpectType { themeProp: string; } - props.theme - - return {} -}) -; - // Can override theme optionally on prop -; +// TODO: Fix types for this usage +// $ExpectError +; // $ExpectError -; +; const Container = styled.div((props: { test: number }) => ({ width: props.test From 84bab5762fa42c2fdcc840694e00d04339592ea6 Mon Sep 17 00:00:00 2001 From: joltmode Date: Sat, 23 Nov 2019 23:46:37 +0200 Subject: [PATCH 10/18] Updated global Theme type declaration to module specific --- docs/typescript.mdx | 20 ++++++++------------ packages/core/types/index.d.ts | 12 +++++------- packages/core/types/tests-theming.tsx | 23 ++++++----------------- packages/core/types/tests.tsx | 16 ++++++++-------- packages/core/types/theming.d.ts | 8 ++++---- packages/serialize/types/index.d.ts | 16 ++++++++-------- packages/styled/types/base.d.ts | 24 ++++++++++-------------- packages/styled/types/index.d.ts | 6 +++--- packages/styled/types/tests-base.tsx | 17 ++++++++--------- 9 files changed, 60 insertions(+), 82 deletions(-) diff --git a/docs/typescript.mdx b/docs/typescript.mdx index 50ce04fd8..0079abcaf 100644 --- a/docs/typescript.mdx +++ b/docs/typescript.mdx @@ -253,14 +253,12 @@ However, you can define a theme type by extending our type declarations via your _emotion.d.ts_ ```typescript -declare global { - namespace Emotion { - export interface Theme { - color: { - primary: string - positive: string - negative: string - } +declare module '@emotion/core' { + export interface Theme { + color: { + primary: string + positive: string + negative: string } } } @@ -268,10 +266,8 @@ declare global { // You are also able to use a 3rd party theme this way: import { MuiTheme } from 'material-ui' -delcare global { - namespace Emotion { - export interface Theme extends MuiTheme {} - } +declare module '@emotion/core' { + export interface Theme extends MuiTheme {} } ``` diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts index 91f09a1b1..0da727530 100644 --- a/packages/core/types/index.d.ts +++ b/packages/core/types/index.d.ts @@ -39,6 +39,9 @@ export { export * from './theming' export * from './helper' +// tslint:disable-next-line: no-empty-interface +export interface Theme {} + export const ThemeContext: Context export const CacheProvider: Provider export function withEmotionCache( @@ -58,7 +61,7 @@ export type InterpolationWithTheme = | ((theme: Theme) => Interpolation) export interface GlobalProps { - styles: Interpolation + styles: Interpolation } /** @@ -86,7 +89,7 @@ export interface ClassNamesContent { css(template: TemplateStringsArray, ...args: Array): string css(...args: Array): string cx(...args: Array): string - theme: Emotion.Theme + theme: Theme } export interface ClassNamesProps { children(content: ClassNamesContent): ReactNode @@ -104,11 +107,6 @@ declare module 'react' { } declare global { - namespace Emotion { - // tslint:disable-next-line: no-empty-interface strict-export-declare-modifiers - export interface Theme {} - } - namespace JSX { /** * Do we need to modify `LibraryManagedAttributes` too, diff --git a/packages/core/types/tests-theming.tsx b/packages/core/types/tests-theming.tsx index 2407b4dc5..990eab19c 100644 --- a/packages/core/types/tests-theming.tsx +++ b/packages/core/types/tests-theming.tsx @@ -2,32 +2,21 @@ // TypeScript Version: 3.1 import * as React from 'react' -import { useTheme, ThemeProvider, withTheme } from '@emotion/core' +import { useTheme, ThemeProvider, withTheme, Theme } from '@emotion/core' import { Interpolation, ObjectInterpolation } from '@emotion/styled/base' -declare global { - namespace Emotion { - interface Theme { - primary: string - secondary: string - } - } -} - -declare const theme: Emotion.Theme +declare const theme: Theme interface Props { prop: boolean } declare const CompFC: React.FC -declare class CompC extends React.Component {} +declare class CompC extends React.Component {} const WrappedCompC = withTheme(CompC) ;{WrappedCompC} ; theme} /> -; ({ ...outerTheme, ...theme })} -/> +; ({ ...outerTheme, ...theme })} /> const ThemedFC = withTheme(CompFC) ; @@ -47,7 +36,7 @@ class CompCWithDefault extends React.Component { } { - const theme: Emotion.Theme = useTheme() + const theme: Theme = useTheme() } const ThemedFCWithDefault = withTheme(CompFCWithDefault) @@ -87,7 +76,7 @@ const ThemedCompWithDefault = withTheme(CompCWithDefault) export type StyleDefinition = Interpolation export type ObjectStyleDefinition = ObjectInterpolation<{ - theme: Emotion.Theme + theme: Theme }> const style: StyleDefinition = ({ theme }) => ({ diff --git a/packages/core/types/tests.tsx b/packages/core/types/tests.tsx index f18a10adc..4f1667556 100644 --- a/packages/core/types/tests.tsx +++ b/packages/core/types/tests.tsx @@ -2,24 +2,24 @@ import { ComponentClass } from 'react' import { ClassNames, - ClassNamesContent, Global, css, jsx, keyframes, withEmotionCache } from '@emotion/core' -; -declare global { - namespace Emotion { - interface Theme { - primaryColor: string - secondaryColor: string - } +declare module '@emotion/core' { + // tslint:disable-next-line: strict-export-declare-modifiers + export interface Theme { + primary: string + secondary: string + primaryColor: string + secondaryColor: string } } +; ; [theme.primaryColor]} /> declare const getRandomColor: () => string diff --git a/packages/core/types/theming.d.ts b/packages/core/types/theming.d.ts index a180fccf3..b3529781d 100644 --- a/packages/core/types/theming.d.ts +++ b/packages/core/types/theming.d.ts @@ -2,7 +2,7 @@ // TypeScript Version: 3.1 import * as React from 'react' -import '@emotion/core' +import { Theme } from '@emotion/core' import { DistributiveOmit, PropsOf } from './helper' import { StyledComponent, @@ -12,7 +12,7 @@ import { } from '@emotion/styled' export interface ThemeProviderProps { - theme: Partial | ((outerTheme: Emotion.Theme) => Emotion.Theme) + theme: Partial | ((outerTheme: Theme) => Theme) children?: React.ReactNode } @@ -24,9 +24,9 @@ export type withTheme = < C extends React.ComponentType> >( component: C -) => React.FC, 'theme'> & { theme?: Emotion.Theme }> +) => React.FC, 'theme'> & { theme?: Theme }> -export function useTheme(): Emotion.Theme +export function useTheme(): Theme export const ThemeProvider: ThemeProvider diff --git a/packages/serialize/types/index.d.ts b/packages/serialize/types/index.d.ts index 4bad424f6..b84197ecc 100644 --- a/packages/serialize/types/index.d.ts +++ b/packages/serialize/types/index.d.ts @@ -1,7 +1,7 @@ // Definitions by: Junyoung Clare Jang // TypeScript Version: 2.8 -import '@emotion/core' +import { Theme } from '@emotion/core' import { RegisteredCache, SerializedStyles } from '@emotion/utils' import * as CSS from 'csstype' @@ -16,10 +16,10 @@ export type CSSPropertiesWithMultiValues = { /** * @desc Following type exists for autocompletion of key. */ -export type CSSPseudos = { +export type CSSPseudos = { [K in CSS.Pseudos]?: ObjectInterpolation } -export interface CSSOthersObject { +export interface CSSOthersObject { [propertiesName: string]: Interpolation } @@ -59,18 +59,18 @@ export type Keyframes = { toString: () => string } & string -export interface ArrayInterpolation +export interface ArrayInterpolation extends Array> {} -export interface ObjectInterpolation +export interface ObjectInterpolation extends CSSPropertiesWithMultiValues, CSSPseudos, CSSOthersObject {} -export interface FunctionInterpolation { +export interface FunctionInterpolation { (mergedProps: MergedProps): Interpolation } -export type Interpolation = +export type Interpolation = | null | undefined | boolean @@ -83,7 +83,7 @@ export type Interpolation = | ObjectInterpolation | FunctionInterpolation -export function serializeStyles( +export function serializeStyles( args: Array>, registered: RegisteredCache, mergedProps?: MP diff --git a/packages/styled/types/base.d.ts b/packages/styled/types/base.d.ts index a3da95783..8ad6cabc2 100644 --- a/packages/styled/types/base.d.ts +++ b/packages/styled/types/base.d.ts @@ -14,7 +14,7 @@ import * as React from 'react' import { ComponentSelector, Interpolation } from '@emotion/serialize' -import { PropsOf, DistributiveOmit } from '@emotion/core' +import { PropsOf, DistributiveOmit, Theme } from '@emotion/core' export { ArrayInterpolation, @@ -76,7 +76,7 @@ export interface CreateStyledComponent< ComponentProps & SpecificComponentProps & StyleProps & - AdditionalProps & { theme: Emotion.Theme } + AdditionalProps & { theme: Theme } > > ): StyledComponent @@ -89,7 +89,7 @@ export interface CreateStyledComponent< Interpolation< ComponentProps & SpecificComponentProps & - AdditionalProps & { theme: Emotion.Theme } + AdditionalProps & { theme: Theme } > > ): StyledComponent @@ -114,19 +114,15 @@ export interface CreateStyled { component: C, options: FilteringStyledOptions, ForwardedProps> ): CreateStyledComponent< - Pick, ForwardedProps> & { theme?: Emotion.Theme }, + Pick, ForwardedProps> & { theme?: Theme }, {}, - { theme: Emotion.Theme } + { theme: Theme } > >>( component: C, options?: StyledOptions> - ): CreateStyledComponent< - PropsOf & { theme?: Emotion.Theme }, - {}, - { theme: Emotion.Theme } - > + ): CreateStyledComponent & { theme?: Theme }, {}, { theme: Theme }> < Tag extends keyof JSX.IntrinsicElements, @@ -135,18 +131,18 @@ export interface CreateStyled { tag: Tag, options: FilteringStyledOptions ): CreateStyledComponent< - { theme?: Emotion.Theme }, + { theme?: Theme }, Pick, - { theme: Emotion.Theme } + { theme: Theme } > ( tag: Tag, options?: StyledOptions ): CreateStyledComponent< - { theme?: Emotion.Theme }, + { theme?: Theme }, JSX.IntrinsicElements[Tag], - { theme: Emotion.Theme } + { theme: Theme } > } diff --git a/packages/styled/types/index.d.ts b/packages/styled/types/index.d.ts index bf1e91571..55f64cb0b 100644 --- a/packages/styled/types/index.d.ts +++ b/packages/styled/types/index.d.ts @@ -1,7 +1,7 @@ // Definitions by: Junyoung Clare Jang // TypeScript Version: 3.2 -import '@emotion/core' +import { Theme } from '@emotion/core' import { CreateStyled as BaseCreateStyled, CreateStyledComponent } from './base' export { @@ -18,9 +18,9 @@ export { export type StyledTags = { [Tag in keyof JSX.IntrinsicElements]: CreateStyledComponent< - { theme?: Emotion.Theme }, + { theme?: Theme }, JSX.IntrinsicElements[Tag], - { theme: Emotion.Theme } + { theme: Theme } > } diff --git a/packages/styled/types/tests-base.tsx b/packages/styled/types/tests-base.tsx index 3c5f812cd..5df973ce3 100644 --- a/packages/styled/types/tests-base.tsx +++ b/packages/styled/types/tests-base.tsx @@ -2,15 +2,14 @@ import * as React from 'react' import styled from '@emotion/styled/base' import isPropValid from '@emotion/is-prop-valid' -declare global { - namespace Emotion { - interface Theme { - primary: string - secondary: string - width: number - colors: { [key: string]: any } - backColor: string - } +declare module '@emotion/core' { + // tslint:disable-next-line: strict-export-declare-modifiers + export interface Theme { + primary: string + secondary: string + width: number + colors: { [key: string]: any } + backColor: string } } From 44adafbafa8e94e3eaaf9c16069f6753887265d4 Mon Sep 17 00:00:00 2001 From: joltmode Date: Sun, 24 Nov 2019 15:09:19 +0200 Subject: [PATCH 11/18] Removed exports from test files --- packages/core/types/tests-theming.tsx | 4 ++-- packages/styled/types/tests.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/core/types/tests-theming.tsx b/packages/core/types/tests-theming.tsx index 990eab19c..c2129fb23 100644 --- a/packages/core/types/tests-theming.tsx +++ b/packages/core/types/tests-theming.tsx @@ -74,8 +74,8 @@ const ThemedCompWithDefault = withTheme(CompCWithDefault) ; // $ExpectError } -export type StyleDefinition = Interpolation -export type ObjectStyleDefinition = ObjectInterpolation<{ +type StyleDefinition = Interpolation +type ObjectStyleDefinition = ObjectInterpolation<{ theme: Theme }> diff --git a/packages/styled/types/tests.tsx b/packages/styled/types/tests.tsx index b1889dec8..cfc183019 100644 --- a/packages/styled/types/tests.tsx +++ b/packages/styled/types/tests.tsx @@ -48,7 +48,7 @@ const Container3 = styled.div(({ theme }) => ({ // who's type clashes with an intrinsic prop. // It makes use of a custom type guard on shouldForwardProp to exclude color -export const Box = styled('div', { +const Box = styled('div', { shouldForwardProp: ( propName ): propName is Exclude => From 2e8b12bf762f9d4d7bff78482690890ea51fcc46 Mon Sep 17 00:00:00 2001 From: joltmode Date: Sun, 24 Nov 2019 15:12:08 +0200 Subject: [PATCH 12/18] Use the incomplete theme prop testcase - Add test case for fully overriding theme --- packages/styled/types/tests.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/styled/types/tests.tsx b/packages/styled/types/tests.tsx index cfc183019..7300040b3 100644 --- a/packages/styled/types/tests.tsx +++ b/packages/styled/types/tests.tsx @@ -25,7 +25,11 @@ const StyledDiv = styled.div({}) ; // Can override theme optionally on prop -// TODO: Fix types for this usage +; + +// Cannot override with incomplete theme on prop // $ExpectError ; From bef05bd4859d22c594c5124992b83134eed512f1 Mon Sep 17 00:00:00 2001 From: joltmode Date: Sun, 24 Nov 2019 15:12:52 +0200 Subject: [PATCH 13/18] Added note about where styled tests get their theme declaration from --- packages/styled/types/tests.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/styled/types/tests.tsx b/packages/styled/types/tests.tsx index 7300040b3..e136cb470 100644 --- a/packages/styled/types/tests.tsx +++ b/packages/styled/types/tests.tsx @@ -1,6 +1,8 @@ import * as React from 'react' import styled from '@emotion/styled' +// This file uses the same Theme declaration from tests-base.tsx + // $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLAnchorElement>, { theme: Theme; }> styled.a // $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLBodyElement>, { theme: Theme; }> From f9ff2b21b5ee0b320d8d78f5ef1fa4865f2457f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 3 Dec 2019 23:41:10 +0100 Subject: [PATCH 14/18] tweak docs --- docs/typescript.mdx | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/typescript.mdx b/docs/typescript.mdx index 0079abcaf..7332791cf 100644 --- a/docs/typescript.mdx +++ b/docs/typescript.mdx @@ -247,8 +247,8 @@ const App = () => ( ### Define a Theme -By default, `props.theme` has an `any` type annotation and works without any errors. -However, you can define a theme type by extending our type declarations via your own declarations file. +By default, `props.theme` is an empty object because it's the only thing that is type-safe as a default. +You can define a theme type by extending our type declarations via your own declarations file. _emotion.d.ts_ @@ -285,6 +285,16 @@ const Button = styled('button')` export default Button ``` +If you were previously relying on `theme` being an `any` type, you have to restore compatibility with: + +_emotion.d.ts_ + +```ts +declare module '@emotion/core' { + export interface Theme extends Record {} +} +``` + ### TypeScript < 2.9 For Typescript <2.9, the generic type version only works with object styles due to https://github.com/Microsoft/TypeScript/issues/11947. From 464922628c9197988ac7ae38d33b84b6eb6d63d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 3 Dec 2019 23:42:36 +0100 Subject: [PATCH 15/18] Remove InterpolationWithTheme type --- packages/core/types/index.d.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts index 0da727530..4db31aa16 100644 --- a/packages/core/types/index.d.ts +++ b/packages/core/types/index.d.ts @@ -56,10 +56,6 @@ export function css( ): SerializedStyles export function css(...args: Array): SerializedStyles -export type InterpolationWithTheme = - | Interpolation - | ((theme: Theme) => Interpolation) - export interface GlobalProps { styles: Interpolation } From 94d0d1f235454fe80f59755af741388ac35c097d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 7 Dec 2019 17:04:43 +0100 Subject: [PATCH 16/18] Move adding Theme to Styled interpolations inline (and not as part of StyleProps) --- packages/styled/types/base.d.ts | 18 +++++------------- packages/styled/types/index.d.ts | 3 +-- packages/styled/types/tests.tsx | 8 ++++---- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/packages/styled/types/base.d.ts b/packages/styled/types/base.d.ts index 8ad6cabc2..15e675675 100644 --- a/packages/styled/types/base.d.ts +++ b/packages/styled/types/base.d.ts @@ -89,6 +89,7 @@ export interface CreateStyledComponent< Interpolation< ComponentProps & SpecificComponentProps & + StyleProps & AdditionalProps & { theme: Theme } > > @@ -113,16 +114,12 @@ export interface CreateStyled { >( component: C, options: FilteringStyledOptions, ForwardedProps> - ): CreateStyledComponent< - Pick, ForwardedProps> & { theme?: Theme }, - {}, - { theme: Theme } - > + ): CreateStyledComponent, ForwardedProps> & { theme?: Theme }> >>( component: C, options?: StyledOptions> - ): CreateStyledComponent & { theme?: Theme }, {}, { theme: Theme }> + ): CreateStyledComponent & { theme?: Theme }> < Tag extends keyof JSX.IntrinsicElements, @@ -132,18 +129,13 @@ export interface CreateStyled { options: FilteringStyledOptions ): CreateStyledComponent< { theme?: Theme }, - Pick, - { theme: Theme } + Pick > ( tag: Tag, options?: StyledOptions - ): CreateStyledComponent< - { theme?: Theme }, - JSX.IntrinsicElements[Tag], - { theme: Theme } - > + ): CreateStyledComponent<{ theme?: Theme }, JSX.IntrinsicElements[Tag]> } declare const styled: CreateStyled diff --git a/packages/styled/types/index.d.ts b/packages/styled/types/index.d.ts index 55f64cb0b..18ff75d7f 100644 --- a/packages/styled/types/index.d.ts +++ b/packages/styled/types/index.d.ts @@ -19,8 +19,7 @@ export { export type StyledTags = { [Tag in keyof JSX.IntrinsicElements]: CreateStyledComponent< { theme?: Theme }, - JSX.IntrinsicElements[Tag], - { theme: Theme } + JSX.IntrinsicElements[Tag] > } diff --git a/packages/styled/types/tests.tsx b/packages/styled/types/tests.tsx index e136cb470..7c084bdd7 100644 --- a/packages/styled/types/tests.tsx +++ b/packages/styled/types/tests.tsx @@ -3,13 +3,13 @@ import styled from '@emotion/styled' // This file uses the same Theme declaration from tests-base.tsx -// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLAnchorElement>, { theme: Theme; }> +// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLAnchorElement>, {}> styled.a -// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLBodyElement>, { theme: Theme; }> +// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLBodyElement>, {}> styled.body -// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLDivElement>, { theme: Theme; }> +// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, DetailedHTMLProps, HTMLDivElement>, {}> styled.div -// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, SVGProps, { theme: Theme; }> +// $ExpectType CreateStyledComponent<{ theme?: Theme | undefined; }, SVGProps, {}> styled.svg { From c2fb7f10bc1c043ee68e41aed18ca7709c848bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 7 Dec 2019 21:27:46 +0100 Subject: [PATCH 17/18] Cleanup Interpolation-related types --- packages/core/types/index.d.ts | 14 +++--- packages/core/types/tests-theming.tsx | 8 ++-- packages/core/types/tests.tsx | 5 +++ packages/create-emotion/types/index.d.ts | 22 +++++----- packages/emotion/types/index.d.ts | 7 ++- packages/serialize/types/index.d.ts | 56 ++++++++---------------- packages/serialize/types/tests.ts | 11 ++--- packages/styled/types/base.d.ts | 3 +- packages/styled/types/index.d.ts | 1 - 9 files changed, 50 insertions(+), 77 deletions(-) diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts index 4db31aa16..904075f36 100644 --- a/packages/core/types/index.d.ts +++ b/packages/core/types/index.d.ts @@ -10,7 +10,6 @@ import { FunctionInterpolation, Interpolation, Keyframes, - ObjectInterpolation, SerializedStyles } from '@emotion/serialize' import { @@ -32,7 +31,6 @@ export { EmotionCache, FunctionInterpolation, Interpolation, - ObjectInterpolation, SerializedStyles } @@ -68,9 +66,9 @@ export function Global(props: GlobalProps): ReactElement export function keyframes( template: TemplateStringsArray, - ...args: Array + ...args: Array ): Keyframes -export function keyframes(...args: Array): Keyframes +export function keyframes(...args: Array): Keyframes export interface ArrayClassNamesArg extends Array {} export type ClassNamesArg = @@ -82,8 +80,8 @@ export type ClassNamesArg = | ArrayClassNamesArg export interface ClassNamesContent { - css(template: TemplateStringsArray, ...args: Array): string - css(...args: Array): string + css(template: TemplateStringsArray, ...args: Array): string + css(...args: Array): string cx(...args: Array): string theme: Theme } @@ -98,7 +96,7 @@ export function ClassNames(props: ClassNamesProps): ReactElement declare module 'react' { interface DOMAttributes { - css?: Interpolation + css?: Interpolation } } @@ -110,7 +108,7 @@ declare global { */ interface IntrinsicAttributes { - css?: Interpolation + css?: Interpolation } } } diff --git a/packages/core/types/tests-theming.tsx b/packages/core/types/tests-theming.tsx index c2129fb23..84ae7f167 100644 --- a/packages/core/types/tests-theming.tsx +++ b/packages/core/types/tests-theming.tsx @@ -3,7 +3,7 @@ import * as React from 'react' import { useTheme, ThemeProvider, withTheme, Theme } from '@emotion/core' -import { Interpolation, ObjectInterpolation } from '@emotion/styled/base' +import { Interpolation, CSSObject } from '@emotion/styled/base' declare const theme: Theme @@ -74,10 +74,8 @@ const ThemedCompWithDefault = withTheme(CompCWithDefault) ; // $ExpectError } -type StyleDefinition = Interpolation -type ObjectStyleDefinition = ObjectInterpolation<{ - theme: Theme -}> +type StyleDefinition = Interpolation<{ theme: Theme }> +type ObjectStyleDefinition = CSSObject const style: StyleDefinition = ({ theme }) => ({ color: theme.primary diff --git a/packages/core/types/tests.tsx b/packages/core/types/tests.tsx index 4f1667556..0c178666c 100644 --- a/packages/core/types/tests.tsx +++ b/packages/core/types/tests.tsx @@ -120,3 +120,8 @@ const anim1 = keyframes` ) }} +;
css` + color: ${theme.secondaryColor}; + `} +/> diff --git a/packages/create-emotion/types/index.d.ts b/packages/create-emotion/types/index.d.ts index 9b29f7b16..a2031ebc1 100644 --- a/packages/create-emotion/types/index.d.ts +++ b/packages/create-emotion/types/index.d.ts @@ -2,17 +2,17 @@ // TypeScript Version: 2.8 import { EmotionCache, Options } from '@emotion/cache' -import { Interpolation } from '@emotion/serialize' +import { CSSInterpolation } from '@emotion/serialize' import { StyleSheet } from '@emotion/sheet' export { - ArrayInterpolation, + CSSInterpolation, + ArrayCSSInterpolation, ComponentSelector, - FunctionInterpolation, - ObjectInterpolation + CSSObject } from '@emotion/serialize' -export { EmotionCache, Interpolation, Options, StyleSheet } +export { EmotionCache, Options, StyleSheet } export interface ArrayClassNamesArg extends Array {} export type ClassNamesArg = @@ -24,21 +24,21 @@ export type ClassNamesArg = | ArrayClassNamesArg export interface Emotion { - css(template: TemplateStringsArray, ...args: Array): string - css(...args: Array): string + css(template: TemplateStringsArray, ...args: Array): string + css(...args: Array): string cx(...classNames: Array): string flush(): void hydrate(ids: Array): void injectGlobal( template: TemplateStringsArray, - ...args: Array + ...args: Array ): void - injectGlobal(...args: Array): void + injectGlobal(...args: Array): void keyframes( template: TemplateStringsArray, - ...args: Array + ...args: Array ): string - keyframes(...args: Array): string + keyframes(...args: Array): string sheet: StyleSheet cache: EmotionCache merge(className: string): string diff --git a/packages/emotion/types/index.d.ts b/packages/emotion/types/index.d.ts index 862779e2b..348736c6a 100644 --- a/packages/emotion/types/index.d.ts +++ b/packages/emotion/types/index.d.ts @@ -5,13 +5,12 @@ import { Emotion } from 'create-emotion' export { ArrayClassNamesArg, - ArrayInterpolation, + ArrayCSSInterpolation, ClassNamesArg, ComponentSelector, EmotionCache, - FunctionInterpolation, - Interpolation, - ObjectInterpolation, + CSSInterpolation, + CSSObject, StyleSheet } from 'create-emotion' diff --git a/packages/serialize/types/index.d.ts b/packages/serialize/types/index.d.ts index b84197ecc..d849db387 100644 --- a/packages/serialize/types/index.d.ts +++ b/packages/serialize/types/index.d.ts @@ -13,21 +13,12 @@ export type CSSPropertiesWithMultiValues = { | CSSProperties[K] | Array> } -/** - * @desc Following type exists for autocompletion of key. - */ -export type CSSPseudos = { - [K in CSS.Pseudos]?: ObjectInterpolation -} -export interface CSSOthersObject { - [propertiesName: string]: Interpolation -} -export type CSSPseudosForCSSObject = { [K in CSS.Pseudos]?: CSSObject } +export type CSSPseudos = { [K in CSS.Pseudos]?: CSSObject } export interface ArrayCSSInterpolation extends Array {} -export type CSSInterpolation = +export type InterpolationPrimitive = | null | undefined | boolean @@ -37,16 +28,17 @@ export type CSSInterpolation = | Keyframes | SerializedStyles | CSSObject - | ArrayCSSInterpolation -export interface CSSOthersObjectForCSSObject { +export type CSSInterpolation = InterpolationPrimitive | ArrayCSSInterpolation + +export interface CSSOthersObject { [propertiesName: string]: CSSInterpolation } export interface CSSObject extends CSSPropertiesWithMultiValues, - CSSPseudosForCSSObject, - CSSOthersObjectForCSSObject {} + CSSPseudos, + CSSOthersObject {} export interface ComponentSelector { __emotion_styles: any @@ -59,32 +51,20 @@ export type Keyframes = { toString: () => string } & string -export interface ArrayInterpolation - extends Array> {} -export interface ObjectInterpolation - extends CSSPropertiesWithMultiValues, - CSSPseudos, - CSSOthersObject {} +export interface ArrayInterpolation + extends Array> {} -export interface FunctionInterpolation { - (mergedProps: MergedProps): Interpolation +export interface FunctionInterpolation { + (props: Props): Interpolation } -export type Interpolation = - | null - | undefined - | boolean - | number - | string - | ComponentSelector - | Keyframes - | SerializedStyles - | ArrayInterpolation - | ObjectInterpolation - | FunctionInterpolation +export type Interpolation = + | InterpolationPrimitive + | ArrayInterpolation + | FunctionInterpolation -export function serializeStyles( - args: Array>, +export function serializeStyles( + args: Array>, registered: RegisteredCache, - mergedProps?: MP + props?: Props ): SerializedStyles diff --git a/packages/serialize/types/tests.ts b/packages/serialize/types/tests.ts index f2f1ae30f..cffb64451 100644 --- a/packages/serialize/types/tests.ts +++ b/packages/serialize/types/tests.ts @@ -1,17 +1,12 @@ -import { - CSSObject, - ObjectInterpolation, - Keyframes, - serializeStyles -} from '@emotion/serialize' +import { CSSObject, Keyframes, serializeStyles } from '@emotion/serialize' declare const testTemplateStringsArray: TemplateStringsArray declare const testKeyframes: Keyframes -const testObjectInterpolation0: ObjectInterpolation = { +const testCSSObject0: CSSObject = { animation: testKeyframes } -const testObjectInterpolation1: ObjectInterpolation = { +const testCSSObject1: CSSObject = { animationName: testKeyframes } diff --git a/packages/styled/types/base.d.ts b/packages/styled/types/base.d.ts index 15e675675..7c8d423fd 100644 --- a/packages/styled/types/base.d.ts +++ b/packages/styled/types/base.d.ts @@ -19,8 +19,7 @@ import { PropsOf, DistributiveOmit, Theme } from '@emotion/core' export { ArrayInterpolation, CSSObject, - FunctionInterpolation, - ObjectInterpolation + FunctionInterpolation } from '@emotion/serialize' export { ComponentSelector, Interpolation } diff --git a/packages/styled/types/index.d.ts b/packages/styled/types/index.d.ts index 18ff75d7f..eb35d2570 100644 --- a/packages/styled/types/index.d.ts +++ b/packages/styled/types/index.d.ts @@ -10,7 +10,6 @@ export { CSSObject, FunctionInterpolation, Interpolation, - ObjectInterpolation, StyledComponent, StyledOptions, CreateStyledComponent From f391e6c40eb5cf6061a9451e990aef2872c784bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 7 Dec 2019 22:02:35 +0100 Subject: [PATCH 18/18] Add changeset --- .changeset/four-cars-tell.md | 15 +++++++++++++++ .changeset/tricky-bears-hope.md | 5 +++++ 2 files changed, 20 insertions(+) create mode 100644 .changeset/four-cars-tell.md create mode 100644 .changeset/tricky-bears-hope.md diff --git a/.changeset/four-cars-tell.md b/.changeset/four-cars-tell.md new file mode 100644 index 000000000..bd1a203ce --- /dev/null +++ b/.changeset/four-cars-tell.md @@ -0,0 +1,15 @@ +--- +'@emotion/core': major +'@emotion/styled': major +--- + +Reworked TypeScript definitions so it's easier to provide a type for Theme. Instead of creating custom instances (like before) you can augment builtin Theme interface like this: + +```ts +declare module '@emotion/core' { + export interface Theme { + primaryColor: string + secondaryColor: string + } +} +``` diff --git a/.changeset/tricky-bears-hope.md b/.changeset/tricky-bears-hope.md new file mode 100644 index 000000000..3f296af40 --- /dev/null +++ b/.changeset/tricky-bears-hope.md @@ -0,0 +1,5 @@ +--- +'@emotion/serialize': minor +--- + +Reworked Interpolation-related types. Correct types should now be provided to all flavours of emotion.