Skip to content

Commit 84ae0f9

Browse files
committedFeb 12, 2021
fix: easier and more precise polymorphic typing

File tree

8 files changed

+77
-321
lines changed

8 files changed

+77
-321
lines changed
 

‎.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module.exports = {
55
},
66
extends: ['airbnb-typescript-prettier'],
77
rules: {
8+
'@typescript-eslint/ban-types': 'off',
89
'@typescript-eslint/no-empty-interface': 'off',
910
'@typescript-eslint/no-empty-function': 'off',
1011
'@typescript-eslint/ban-ts-comment': 'off',

‎packages/visage-core/src/__tests__/typeTest.tsx

+6-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@
66
import React from 'react';
77
import { createComponent } from '../createComponent';
88
import { VisageComponent } from '../types';
9-
import { StyleSheet } from '../styleSheet';
9+
10+
const Div = createComponent('div');
11+
12+
<Div />;
1013

1114
declare function FC(p: { test: boolean }): JSX.Element;
1215

@@ -191,8 +194,8 @@ const AssignComplexMemoAndForward: VisageComponent<
191194
> = React.memo(
192195
React.forwardRef(
193196
(
194-
props: JSX.IntrinsicElements['h1'] & { test: boolean },
195-
ref: React.Ref<HTMLHeadingElement>,
197+
props: JSX.IntrinsicElements['div'] & { test: boolean },
198+
ref: React.Ref<HTMLDivElement>,
196199
) => null,
197200
),
198201
);

‎packages/visage-core/src/createComponent.ts

+5-11
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,11 @@ const DEFAULT_STYLE_SHEET = {};
2424
*/
2525
export function createComponent<
2626
TDefaultComponent extends ComponentConstraint,
27-
TVariants extends Record<string, any>[] = Record<string, any>[],
28-
TVariantIntersection = UnionToIntersection<TVariants[number]>,
29-
TProps extends Omit<
30-
ExtractVisageComponentProps<TDefaultComponent>,
31-
keyof TVariantIntersection
32-
> &
33-
TVariantIntersection = Omit<
34-
ExtractVisageComponentProps<TDefaultComponent>,
35-
keyof TVariantIntersection
36-
> &
37-
TVariantIntersection,
27+
TVariants extends undefined | Record<string, unknown>[] = undefined,
28+
TProps = TVariants extends Record<string, unknown>[]
29+
? ExtractVisageComponentProps<TDefaultComponent> &
30+
UnionToIntersection<TVariants[number]>
31+
: ExtractVisageComponentProps<TDefaultComponent>,
3832
TDefaultProps extends Partial<TProps> = any
3933
>(
4034
defaultAs: TDefaultComponent,

‎packages/visage-core/src/types.ts

+24-251
Large diffs are not rendered by default.
+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useMemo } from 'react';
2-
import { ExtractArgs, ExtractReturn } from './types';
32

43
/**
54
* Uses statically declared function in useMemo
@@ -8,8 +7,8 @@ import { ExtractArgs, ExtractReturn } from './types';
87
*/
98
export function useStaticMemo<TFunction extends (...args: any[]) => any>(
109
fn: TFunction,
11-
deps: ExtractArgs<TFunction>,
12-
): ExtractReturn<TFunction> {
10+
deps: Parameters<TFunction>,
11+
): ReturnType<TFunction> {
1312
// eslint-disable-next-line react-hooks/exhaustive-deps
1413
return useMemo(() => fn(...deps), deps);
1514
}

‎packages/visage/src/components/Heading.tsx

+37-49
Original file line numberDiff line numberDiff line change
@@ -103,43 +103,38 @@ export interface HeadingProps extends H1Props {
103103

104104
export const Heading = markAsVisageComponent(
105105
memo(
106-
forwardRef(
107-
(
108-
{ level = 1, ...restProps }: JSX.IntrinsicElements['h1'] & HeadingProps,
109-
ref: any,
110-
) => {
111-
let as = h1;
112-
113-
switch (level) {
114-
case 2:
115-
as = h2;
116-
break;
117-
case 3:
118-
as = h3;
119-
break;
120-
case 4:
121-
as = h4;
122-
break;
123-
case 5:
124-
as = h5;
125-
break;
126-
case 6:
127-
as = h6;
128-
}
129-
130-
return createElement(as, {
131-
ref,
132-
// @ts-ignore
133-
'data-level': level,
134-
...restProps,
135-
});
136-
},
137-
),
106+
forwardRef<HTMLHeadingElement, HeadingProps>(function Heading(
107+
{ level = 1, ...restProps }: HeadingProps,
108+
ref,
109+
) {
110+
let as = h1;
111+
112+
switch (level) {
113+
case 2:
114+
as = h2;
115+
break;
116+
case 3:
117+
as = h3;
118+
break;
119+
case 4:
120+
as = h4;
121+
break;
122+
case 5:
123+
as = h5;
124+
break;
125+
case 6:
126+
as = h6;
127+
}
128+
129+
return createElement(as, {
130+
ref,
131+
'data-level': level,
132+
...restProps,
133+
});
134+
}),
138135
),
139136
);
140137

141-
Heading.displayName = 'Heading';
142-
143138
const defaultMask = [6];
144139

145140
interface HeadingSkeletonProps {
@@ -151,20 +146,13 @@ interface HeadingSkeletonProps {
151146

152147
export const HeadingSkeleton = markAsVisageComponent(
153148
memo(
154-
forwardRef(
155-
(
156-
{
157-
mask = defaultMask,
158-
...restProps
159-
}: JSX.IntrinsicElements['h1'] & HeadingProps & HeadingSkeletonProps,
160-
ref: any,
161-
) => {
162-
return (
163-
<Heading as={SkeletonSentence} mask={mask} ref={ref} {...restProps} />
164-
);
165-
},
166-
),
149+
forwardRef<
150+
HTMLDivElement,
151+
Omit<HeadingProps & HeadingSkeletonProps, 'ref'>
152+
>(function HeadingSkeleton({ mask = defaultMask, ...restProps }, ref) {
153+
return (
154+
<Heading as={SkeletonSentence} mask={mask} ref={ref} {...restProps} />
155+
);
156+
}),
167157
),
168158
);
169-
170-
HeadingSkeleton.displayName = 'HeadingSkeleton';

‎packages/visage/src/hooks/useOnRenderEffect.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { useEffect, useMemo } from 'react';
2-
import { ExtractArgs } from '@byteclaw/visage-core';
32

43
/**
54
* Works similarly as useEffect except it runs effect before children are rendered
@@ -27,7 +26,7 @@ export function useOnRenderEffect(
2726
*/
2827
export function useStaticOnRenderEffect<
2928
T extends (...effectArgs: any[]) => void | (() => void)
30-
>(effect: T, ...args: ExtractArgs<T>): void {
29+
>(effect: T, ...args: Parameters<T>): void {
3130
// eslint-disable-next-line react-hooks/exhaustive-deps
3231
const unregister = useMemo(() => effect(...args), [effect, ...args]);
3332

‎packages/visage/src/hooks/useStaticEffect.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import { ExtractArgs } from '@byteclaw/visage-core';
21
import { useEffect } from 'react';
32

43
/**
54
* Creates a static effect that is called with provided args
65
*/
76
export function useStaticEffect<T extends (...effectArgs: any[]) => void>(
87
effectFn: T,
9-
...args: ExtractArgs<T>
8+
...args: Parameters<T>
109
): void {
1110
useEffect(() => {
1211
return effectFn(...args);

0 commit comments

Comments
 (0)
Please sign in to comment.