From e9a525d62e0f05c85cd49ec487bf27cbea3852fc Mon Sep 17 00:00:00 2001 From: Pat Sissons Date: Sat, 23 Nov 2019 15:37:06 -0800 Subject: [PATCH] some minor adjustments to the types --- packages/native/types/base.d.ts | 103 +++++++++++++++++-------------- packages/native/types/index.d.ts | 17 ++--- packages/native/types/tests.tsx | 29 +++++---- 3 files changed, 85 insertions(+), 64 deletions(-) diff --git a/packages/native/types/base.d.ts b/packages/native/types/base.d.ts index 02b0bd6736..3352033ee3 100644 --- a/packages/native/types/base.d.ts +++ b/packages/native/types/base.d.ts @@ -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 +export type ObjectInterpolation = RN.ViewStyle | RN.TextStyle | RN.ImageStyle -export interface ArrayInterpolation extends Array> {} - -// @ts-ignore -export interface ObjectInterpolation - extends RN.ViewStyle, - RN.TextStyle, - RN.ImageStyle {} - +export interface ArrayInterpolation + extends Array> {} export interface FunctionInterpolation { (mergedProps: MergedProps): Interpolation } -export type Interpolation = +export type Interpolation = | null | undefined | boolean @@ -32,7 +26,7 @@ export type Interpolation = | ArrayInterpolation | FunctionInterpolation -type ReactNativeTags = +type ReactNativeComponentNames = | 'ActivityIndicator' | 'ActivityIndicatorIOS' | 'Button' @@ -73,9 +67,10 @@ type ReactNativeTags = | 'ViewPagerAndroid' | 'WebView' -export type ReactNativeElements = { - [Tag in ReactNativeTags]: PropsOf -} +export type ReactNativeComponents = Pick +export type ReactNativeComponentProps< + ComponentName extends ReactNativeComponentNames +> = ComponentPropsWithoutRef /** Same as StyledOptions but shouldForwardProp must be a type guard */ export interface FilteringStyledOptions< @@ -89,21 +84,26 @@ export interface StyledOptions { shouldForwardProp?(propName: PropertyKey): boolean } +export interface StyledWithComponent { + withComponent< + Component extends ComponentType> + >( + component: Component + ): StyledComponent> + withComponent( + component: ReactNativeComponents[ComponentName] + ): StyledComponent> +} + /** * @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 { - withComponent>>( - component: C - ): StyledComponent> - withComponent( - tag: Tag - ): StyledComponent -} +> = ComponentType & + StyledWithComponent /** * @typeparam ComponentProps Props which will be included when withComponent is called @@ -149,45 +149,58 @@ export interface CreateStyledComponent< */ export interface CreateStyled { < - C extends React.ComponentType>, - ForwardedProps extends keyof React.ComponentProps< - C - > = keyof React.ComponentProps + Component extends ComponentType>, + ForwardedProps extends keyof ComponentPropsWithoutRef< + Component + > = keyof ComponentPropsWithoutRef >( - component: C, - options: FilteringStyledOptions, ForwardedProps> + component: Component, + options: FilteringStyledOptions< + ComponentPropsWithoutRef, + ForwardedProps + > ): CreateStyledComponent< - Pick, ForwardedProps> & { theme?: Theme }, + Pick, ForwardedProps> & { + theme?: Theme + }, {}, { theme: Theme } > - >>( - component: C, - options?: StyledOptions> - ): CreateStyledComponent & { theme?: Theme }, {}, { theme: Theme }> + >>( + component: Component, + options?: StyledOptions> + ): CreateStyledComponent< + ComponentPropsWithoutRef & { 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 >( - tag: Tag, - options: FilteringStyledOptions + component: ReactNativeComponents[ComponentName], + options: FilteringStyledOptions< + ReactNativeComponentProps, + ForwardedProps + > ): CreateStyledComponent< { theme?: Theme }, - Pick, + Pick, ForwardedProps>, { theme: Theme } > - ( - tag: Tag, - options?: StyledOptions + ( + component: ReactNativeComponents[ComponentName], + options?: StyledOptions> ): CreateStyledComponent< { theme?: Theme }, - ReactNativeElements[Tag], + ReactNativeComponentProps, { theme: Theme } > } -declare const styled: CreateStyled -export default styled +export const styled: CreateStyled diff --git a/packages/native/types/index.d.ts b/packages/native/types/index.d.ts index e5222c5f23..ec4d102cf7 100644 --- a/packages/native/types/index.d.ts +++ b/packages/native/types/index.d.ts @@ -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( @@ -25,17 +28,17 @@ export function css( ): ReactNativeStyle export function css(...args: Array): ReactNativeStyle -export type StyledTags = { - [Tag in keyof ReactNativeElements]: CreateStyledComponent< +export type StyledComponents = { + [ComponentName in ReactNativeComponentNames]: CreateStyledComponent< { theme?: Theme }, - ReactNativeElements[Tag], + ReactNativeComponentProps, { theme: Theme } > } export interface CreateStyled extends BaseCreateStyled, - StyledTags {} + StyledComponents {} declare const styled: CreateStyled export default styled diff --git a/packages/native/types/tests.tsx b/packages/native/types/tests.tsx index 98e9d69a8e..374ce9e4f2 100644 --- a/packages/native/types/tests.tsx +++ b/packages/native/types/tests.tsx @@ -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, @@ -17,7 +17,7 @@ const className = css` ${cssObject} ` -const className2: ReturnType = css(cssObject) +const className2: ReactNativeStyle = css(cssObject) css([{ display: 'none' }, [{ position: 'relative' }, { width: 100 }]]) @@ -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` background-color: blue; // ${({ foo }) => foo} ` -export const ThemedView = (styled as Styled).View< - AdditionalProps ->` - background-color: ${({ theme }) => theme.color.positive}; // ${({ - foo, - bar -}) => foo + bar} +export const ThemedView = (styled as CreateStyled).View` + background-color: ${({ theme }) => theme.color.positive}; // ${({ bar }) => + bar} ` export const ComposedView = styled.View` @@ -80,5 +76,14 @@ const theme: Theme = { } } -export const themed = +export const themed = export const composed = + +function MyComponent(_props: AdditionalProps) { + return null +} + +styled(MyComponent)({ width: 100 }) +styled(MyComponent)(({ bar }) => ({ color: bar })) +styled(View)({ width: 100 }) +styled(View)(({ foo, testID }) => ({ color: foo, testID }))