From 9f5e6af120884b1b7d7e335feab566f29ab7c903 Mon Sep 17 00:00:00 2001 From: BenSeage Date: Wed, 4 Jan 2023 10:07:22 +0800 Subject: [PATCH] New(React): Optional generic type --- packages/react/src/index.tsx | 27 +++++++++------------------ packages/react/tests/index.test.tsx | 24 ++++++++++++------------ 2 files changed, 21 insertions(+), 30 deletions(-) diff --git a/packages/react/src/index.tsx b/packages/react/src/index.tsx index 721360b..ab4b23f 100644 --- a/packages/react/src/index.tsx +++ b/packages/react/src/index.tsx @@ -17,6 +17,7 @@ type MasterComponentProps, E extends object = object> = React.ForwardRefExoticComponent & React.RefAttributes> & { tag: K, params: TagParams }; type ParamsType, E extends object = object> = Array<((props: MasterComponentProps) => baseLoopType | undefined) | baseLoopType>; + type ReturnType, E extends object = object> = | baseType>( firstParam: F, ...params: F extends MasterExoticComponent @@ -27,25 +28,15 @@ type ReturnType, E ex : MasterExoticComponent) const style: { - [key in IntrinsicElementsKeys]: | baseType, E extends object = object>( - firstParam: F, - ...params: F extends MasterExoticComponent - ? never - : ParamsType - ) => (F extends MasterExoticComponent - ? ReturnType - : MasterExoticComponent) + [key in IntrinsicElementsKeys]: (, E extends object = object>(firstParam: F) => F extends MasterExoticComponent ? ReturnType : never) + & ((firstParam: TemplateStringsArray | baseType, ...params: ParamsType) => MasterExoticComponent) +} & { + , E extends object = object>(firstParam: F): F extends MasterExoticComponent ? ReturnType : never +} & { + (firstParam: TemplateStringsArray | baseType, ...params: ParamsType<'div', E>): MasterExoticComponent<'div', E> } & { - | React.ComponentType | baseType, E extends object = object>( - firstParam: F, - ...params: F extends MasterExoticComponent - ? never - : ParamsType<'div', E> - ): (F extends MasterExoticComponent - ? ReturnType - : F extends React.ComponentType - ? ReturnType - : MasterExoticComponent<'div', E>) + //@ts-ignore + , E extends object = object>(firstParam: F, ...params: F extends React.ComponentType ? ParamsType<'div', RE & E> : never): F extends React.ComponentType ? ReturnType> :never } = new Proxy( ((firstParam, ...params) => { return (Array.isArray(firstParam) && 'raw' in firstParam || typeof firstParam !== 'object' || !('render' in firstParam)) diff --git a/packages/react/tests/index.test.tsx b/packages/react/tests/index.test.tsx index c5d4b58..7dd1b65 100644 --- a/packages/react/tests/index.test.tsx +++ b/packages/react/tests/index.test.tsx @@ -4,7 +4,7 @@ import ReactDOMServer from 'react-dom/server' const { renderToStaticMarkup } = ReactDOMServer -const Button = style.button` +const Button = style.button<{ $color: string }>` inline-flex center-content ${['font:14', 'font:semibold']} ${{ test: true, test2: false, test3: true }} @@ -18,22 +18,22 @@ test('Basic', () => { }) test('Extend', () => { - const ExtendButton = style(Button)`bg:${({ $color }: any) => $color}-54:hover` + const ExtendButton = style(Button)`bg:${({ $color }) => $color}-54:hover` expect(renderToStaticMarkup(Extend)) .toBe('') - const AButton = style.a(Button)`` + const AButton = style.a(Button)`` expect(renderToStaticMarkup(Tag Extend)) .toBe('Tag Extend') const CustomComponent = forwardRef((props: { $type: string }, ref: any) => ) - const ExtendCustomComponent = style(CustomComponent)`inline-flex center-content font:14 font:semibold ${(props) => props.$type}` - expect(renderToStaticMarkup(Extend Custom Component)) - .toBe('Extend Custom Component') + const ExtendCustomComponent = style(CustomComponent)`inline-flex center-content font:14 font:semibold ${(props) => props.$type} ${(props) => props.$newType}` + expect(renderToStaticMarkup(Extend Custom Component)) + .toBe('Extend Custom Component') }) test('Prop composition', () => { - const Button = style.button`font:semibold rounded + const Button = style.button<{ $intent: string, $size: string }>`font:semibold rounded ${{ intent: { primary: 'bg:blue-50 fg:white bg:blue-60:hover', @@ -47,9 +47,9 @@ test('Prop composition', () => { ${{ intent: 'primary', size: 'md', $: 'uppercase' }} ${({ $intent, $size }) => $intent && $size && 'font:italic'} ` + expect(renderToStaticMarkup(') - expect(renderToStaticMarkup(') @@ -75,7 +75,7 @@ test('Prop composition', () => { }) test('Alternative syntax', () => { - const Div = style( + const Div = style<{ $intent: string, $size: string }>( 'font:semibold rounded', { intent: { @@ -88,12 +88,12 @@ test('Alternative syntax', () => { } }, { intent: 'primary', size: 'md', $: 'uppercase' }, - ({ $intent, $size }) => $intent && $size && 'font:italic' + ({ $intent, $size }) => $intent && $size && `font:italic` ) expect(renderToStaticMarkup(
)) .toBe('
') - const Button = style.button( + const Button = style.button<{ $intent: string, $size: string }>( 'font:semibold rounded', { intent: { @@ -121,7 +121,7 @@ test('Alternative syntax', () => { expect(renderToStaticMarkup(') - const ExtendButton = style(Button)( + const ExtendButton = style(Button)( { intent: { primary: 'bg:blue-70 fg:black bg:blue-80:hover'