Skip to content

Commit

Permalink
some minor adjustments to the types
Browse files Browse the repository at this point in the history
  • Loading branch information
Pat Sissons committed Nov 23, 2019
1 parent c3d48f9 commit e9a525d
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 64 deletions.
103 changes: 58 additions & 45 deletions packages/native/types/base.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,19 @@

import { ComponentPropsWithoutRef, ComponentType } from 'react'
import * as RN from 'react-native'
import { PropsOf } from '@emotion/core'

type ReactNative = typeof RN

export type ReactNativeStyle = ReturnType<ReactNative['StyleSheet']['flatten']>
export type ObjectInterpolation = RN.ViewStyle | RN.TextStyle | RN.ImageStyle

export interface ArrayInterpolation<MP> extends Array<Interpolation<MP>> {}

// @ts-ignore
export interface ObjectInterpolation
extends RN.ViewStyle,
RN.TextStyle,
RN.ImageStyle {}

export interface ArrayInterpolation<MergedProps>
extends Array<Interpolation<MergedProps>> {}
export interface FunctionInterpolation<MergedProps> {
(mergedProps: MergedProps): Interpolation<MergedProps>
}

export type Interpolation<MergedProps = undefined> =
export type Interpolation<MergedProps = unknown> =
| null
| undefined
| boolean
Expand All @@ -32,7 +26,7 @@ export type Interpolation<MergedProps = undefined> =
| ArrayInterpolation<MergedProps>
| FunctionInterpolation<MergedProps>

type ReactNativeTags =
type ReactNativeComponentNames =
| 'ActivityIndicator'
| 'ActivityIndicatorIOS'
| 'Button'
Expand Down Expand Up @@ -73,9 +67,10 @@ type ReactNativeTags =
| 'ViewPagerAndroid'
| 'WebView'

export type ReactNativeElements = {
[Tag in ReactNativeTags]: PropsOf<ReactNative[Tag]>
}
export type ReactNativeComponents = Pick<ReactNative, ReactNativeComponentNames>
export type ReactNativeComponentProps<
ComponentName extends ReactNativeComponentNames
> = ComponentPropsWithoutRef<ReactNativeComponents[ComponentName]>

/** Same as StyledOptions but shouldForwardProp must be a type guard */
export interface FilteringStyledOptions<
Expand All @@ -89,21 +84,26 @@ export interface StyledOptions<Props> {
shouldForwardProp?(propName: PropertyKey): boolean
}

export interface StyledWithComponent<ComponentProps extends {}> {
withComponent<
Component extends ComponentType<ComponentPropsWithoutRef<Component>>
>(
component: Component
): StyledComponent<ComponentProps & ComponentPropsWithoutRef<Component>>
withComponent<ComponentName extends ReactNativeComponentNames>(
component: ReactNativeComponents[ComponentName]
): StyledComponent<ComponentProps, ReactNativeComponentProps<ComponentName>>
}

/**
* @typeparam ComponentProps Props which will be included when withComponent is called
* @typeparam SpecificComponentProps Props which will *not* be included when withComponent is called
*/
export interface StyledComponent<
export type StyledComponent<
ComponentProps extends {},
SpecificComponentProps extends {} = {}
> extends React.FC<ComponentProps & SpecificComponentProps> {
withComponent<C extends React.ComponentType<React.ComponentProps<C>>>(
component: C
): StyledComponent<ComponentProps & PropsOf<C>>
withComponent<Tag extends keyof ReactNativeElements>(
tag: Tag
): StyledComponent<ComponentProps, ReactNativeElements[Tag]>
}
> = ComponentType<ComponentProps & SpecificComponentProps> &
StyledWithComponent<ComponentProps>

/**
* @typeparam ComponentProps Props which will be included when withComponent is called
Expand Down Expand Up @@ -149,45 +149,58 @@ export interface CreateStyledComponent<
*/
export interface CreateStyled<Theme extends {} = any> {
<
C extends React.ComponentType<React.ComponentProps<C>>,
ForwardedProps extends keyof React.ComponentProps<
C
> = keyof React.ComponentProps<C>
Component extends ComponentType<ComponentPropsWithoutRef<Component>>,
ForwardedProps extends keyof ComponentPropsWithoutRef<
Component
> = keyof ComponentPropsWithoutRef<Component>
>(
component: C,
options: FilteringStyledOptions<PropsOf<C>, ForwardedProps>
component: Component,
options: FilteringStyledOptions<
ComponentPropsWithoutRef<Component>,
ForwardedProps
>
): CreateStyledComponent<
Pick<PropsOf<C>, ForwardedProps> & { theme?: Theme },
Pick<ComponentPropsWithoutRef<Component>, ForwardedProps> & {
theme?: Theme
},
{},
{ theme: Theme }
>

<C extends React.ComponentType<React.ComponentProps<C>>>(
component: C,
options?: StyledOptions<PropsOf<C>>
): CreateStyledComponent<PropsOf<C> & { theme?: Theme }, {}, { theme: Theme }>
<Component extends ComponentType<ComponentPropsWithoutRef<Component>>>(
component: Component,
options?: StyledOptions<ComponentPropsWithoutRef<Component>>
): CreateStyledComponent<
ComponentPropsWithoutRef<Component> & { theme?: Theme },
{},
{ theme: Theme }
>

<
Tag extends keyof ReactNativeElements,
ForwardedProps extends keyof ReactNativeElements[Tag] = keyof ReactNativeElements[Tag]
ComponentName extends ReactNativeComponentNames,
ForwardedProps extends keyof ReactNativeComponentProps<
ComponentName
> = keyof ReactNativeComponentProps<ComponentName>
>(
tag: Tag,
options: FilteringStyledOptions<ReactNativeElements[Tag], ForwardedProps>
component: ReactNativeComponents[ComponentName],
options: FilteringStyledOptions<
ReactNativeComponentProps<ComponentName>,
ForwardedProps
>
): CreateStyledComponent<
{ theme?: Theme },
Pick<ReactNativeElements[Tag], ForwardedProps>,
Pick<ReactNativeComponentProps<ComponentName>, ForwardedProps>,
{ theme: Theme }
>

<Tag extends keyof ReactNativeElements>(
tag: Tag,
options?: StyledOptions<ReactNativeElements[Tag]>
<ComponentName extends ReactNativeComponentNames>(
component: ReactNativeComponents[ComponentName],
options?: StyledOptions<ReactNativeComponentProps<ComponentName>>
): CreateStyledComponent<
{ theme?: Theme },
ReactNativeElements[Tag],
ReactNativeComponentProps<ComponentName>,
{ theme: Theme }
>
}

declare const styled: CreateStyled
export default styled
export const styled: CreateStyled
17 changes: 10 additions & 7 deletions packages/native/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import {
CreateStyledComponent,
Interpolation,
ReactNativeStyle,
ReactNativeElements
ReactNativeComponentNames,
ReactNativeComponentProps,
ReactNativeComponents
} from './base'

export {
ArrayInterpolation,
CreateStyledComponent,
FunctionInterpolation,
Interpolation,
ObjectInterpolation,
ReactNativeStyle,
StyledComponent,
StyledOptions,
CreateStyledComponent
StyledOptions
} from './base'

export function css(
Expand All @@ -25,17 +28,17 @@ export function css(
): ReactNativeStyle
export function css(...args: Array<Interpolation>): ReactNativeStyle

export type StyledTags<Theme extends {} = any> = {
[Tag in keyof ReactNativeElements]: CreateStyledComponent<
export type StyledComponents<Theme extends {} = any> = {
[ComponentName in ReactNativeComponentNames]: CreateStyledComponent<
{ theme?: Theme },
ReactNativeElements[Tag],
ReactNativeComponentProps<ComponentName>,
{ theme: Theme }
>
}

export interface CreateStyled<Theme extends {} = any>
extends BaseCreateStyled<Theme>,
StyledTags<Theme> {}
StyledComponents<Theme> {}

declare const styled: CreateStyled
export default styled
29 changes: 17 additions & 12 deletions packages/native/types/tests.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as React from 'react'
import { StyleSheet } from 'react-native'
import styled, { css, Styled } from '@emotion/native'
import { View } from 'react-native'
import styled, { CreateStyled, css, ReactNativeStyle } from '@emotion/native'

const cssObject = {
height: 100,
Expand All @@ -17,7 +17,7 @@ const className = css`
${cssObject}
`

const className2: ReturnType<typeof StyleSheet.flatten> = css(cssObject)
const className2: ReactNativeStyle = css(cssObject)

css([{ display: 'none' }, [{ position: 'relative' }, { width: 100 }]])

Expand Down Expand Up @@ -49,17 +49,13 @@ export const InferredPropsView = styled.View`
background-color: green; // ${({ testID }) => testID}
`

export const InferredExtraPropsView = (styled as Styled<{}, ExtraProps>).View`
export const InferredExtraPropsView = styled.View<ExtraProps>`
background-color: blue; // ${({ foo }) => foo}
`

export const ThemedView = (styled as Styled<Theme, ExtraProps>).View<
AdditionalProps
>`
background-color: ${({ theme }) => theme.color.positive}; // ${({
foo,
bar
}) => foo + bar}
export const ThemedView = (styled as CreateStyled<Theme>).View<AdditionalProps>`
background-color: ${({ theme }) => theme.color.positive}; // ${({ bar }) =>
bar}
`

export const ComposedView = styled.View`
Expand All @@ -80,5 +76,14 @@ const theme: Theme = {
}
}

export const themed = <ThemedView foo="foo" bar="bar" theme={theme} />
export const themed = <ThemedView bar="bar" theme={theme} />
export const composed = <ComposedView theme={theme} />

function MyComponent(_props: AdditionalProps) {
return null
}

styled(MyComponent)({ width: 100 })
styled(MyComponent)(({ bar }) => ({ color: bar }))
styled(View)({ width: 100 })
styled(View)<ExtraProps>(({ foo, testID }) => ({ color: foo, testID }))

0 comments on commit e9a525d

Please sign in to comment.