Skip to content

Commit 9189668

Browse files
committed
fix: OptionType and GroupedOptionType with generics
1 parent 7d508b7 commit 9189668

File tree

4 files changed

+50
-40
lines changed

4 files changed

+50
-40
lines changed

src/Fields/FieldWrapper.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
UseControllerProps,
66
FieldPathValue,
77
FieldPath,
8-
UnpackNestedValue,
98
} from 'react-hook-form';
109

1110
import { Form, FormItemProps } from '../Form';
@@ -14,20 +13,20 @@ import { useFieldContext } from './FieldProvider';
1413

1514
export type FieldWrapperProps<
1615
TFieldValues extends FieldValues,
17-
TName extends FieldPath<TFieldValues>,
16+
TFieldPath extends FieldPath<TFieldValues>,
1817
> = {
1918
children: ReactNode;
20-
controller: UseControllerProps<TFieldValues, TName>;
21-
formItem?: FormItemProps<
22-
UnpackNestedValue<FieldPathValue<TFieldValues, TName>>
23-
>;
19+
controller: UseControllerProps<TFieldValues, TFieldPath>;
20+
formItem?: FormItemProps<FieldPathValue<TFieldValues, TFieldPath>>;
2421
};
2522

2623
export function FieldWrapper<
2724
TFieldValues extends FieldValues,
28-
TName extends FieldPath<TFieldValues>,
29-
>(props: FieldWrapperProps<TFieldValues, TName>) {
30-
const { fieldState } = useController<TFieldValues, TName>(props.controller);
25+
TFieldPath extends FieldPath<TFieldValues>,
26+
>(props: FieldWrapperProps<TFieldValues, TFieldPath>) {
27+
const { fieldState } = useController<TFieldValues, TFieldPath>(
28+
props.controller,
29+
);
3130

3231
const { formItemProps } = useFieldContext();
3332

src/Fields/SelectField.tsx

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,47 @@
1-
import { DefaultOptionType } from 'antd/lib/select';
21
import React from 'react';
32
import {
43
useController,
54
FieldPath,
65
FieldPathValue,
76
FieldValues,
87
UseControllerProps,
9-
UnpackNestedValue,
108
} from 'react-hook-form';
119

12-
import { GroupedOptionType, Select, SelectProps } from '../Select';
10+
import { OptionType, GroupedOptionType, Select, SelectProps } from '../Select';
1311

1412
import { useFieldContext } from './FieldProvider';
1513
import { FieldWrapper, FieldWrapperProps } from './FieldWrapper';
1614

1715
type SelectFieldProps<
1816
TFieldValues extends FieldValues,
19-
TName extends FieldPath<TFieldValues>,
20-
TOption extends DefaultOptionType | GroupedOptionType,
21-
> = UseControllerProps<TFieldValues, TName> &
22-
Pick<FieldWrapperProps<TFieldValues, TName>, 'formItem'> & {
23-
component?: SelectProps<
24-
UnpackNestedValue<FieldPathValue<TFieldValues, TName>>,
25-
TOption
26-
>;
17+
TFieldPath extends FieldPath<TFieldValues>,
18+
TFieldPathValue extends FieldPathValue<TFieldValues, TFieldPath>,
19+
TOption extends
20+
| OptionType<TFieldPathValue>
21+
| GroupedOptionType<TFieldPathValue>,
22+
> = UseControllerProps<TFieldValues, TFieldPath> &
23+
Pick<FieldWrapperProps<TFieldValues, TFieldPath>, 'formItem'> & {
24+
component?: SelectProps<TFieldPathValue, TOption>;
2725
};
2826

2927
export function SelectField<
3028
TFieldValues extends FieldValues = FieldValues,
31-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
32-
TOption extends DefaultOptionType | GroupedOptionType = DefaultOptionType,
29+
TFieldPath extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
30+
TFieldPathValue extends FieldPathValue<
31+
TFieldValues,
32+
TFieldPath
33+
> = FieldPathValue<TFieldValues, TFieldPath>,
34+
TOption extends
35+
| OptionType<TFieldPathValue>
36+
| GroupedOptionType<TFieldPathValue> = OptionType<TFieldPathValue>,
3337
>({
3438
formItem,
3539
component,
3640
...controller
37-
}: SelectFieldProps<TFieldValues, TName, TOption>) {
41+
}: SelectFieldProps<TFieldValues, TFieldPath, TFieldPathValue, TOption>) {
3842
const {
3943
field: { onChange, ...fieldProps },
40-
} = useController<TFieldValues, TName>(controller);
44+
} = useController<TFieldValues, TFieldPath>(controller);
4145

4246
const { disabled } = useFieldContext();
4347

src/Fields/index.stories.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ function AllFields() {
199199
label: 'Select',
200200
}}
201201
component={{
202-
options: ['a', 'b'].map(toFormInputOption),
202+
options: (['a', 'b'] as const).map(toFormInputOption),
203203
}}
204204
/>
205205
<SwitchField

src/Select/index.tsx

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,36 @@
11
import { Select as AntdSelect, SelectProps as AntdSelectProps } from 'antd';
2-
import { DefaultOptionType } from 'antd/lib/select';
32
import { BaseSelectRef } from 'rc-select';
43
import React, {
54
ForwardedRef,
65
forwardRef,
76
ReactElement,
7+
ReactNode,
88
RefAttributes,
99
useCallback,
1010
} from 'react';
1111
import styled from 'styled-components';
1212

1313
import { fontSizeFromTheme } from '../styled-utils';
1414

15-
/** As described in https://4x.ant.design/components/select/#components-select-demo-optgroup. */
16-
export type GroupedOptionType = {
17-
label: string;
18-
options: Array<DefaultOptionType>;
15+
export type OptionType<TValue = unknown> = {
16+
label: ReactNode;
17+
value: TValue;
1918
};
2019

21-
export type { DefaultOptionType } from 'antd/lib/select';
20+
/** As described in https://4x.ant.design/components/select/#components-select-demo-optgroup. */
21+
export type GroupedOptionType<TValue = unknown> = {
22+
label: ReactNode;
23+
options: Array<OptionType<TValue>>;
24+
};
2225

2326
export type { FilterFunc as FilterOptionFunction } from 'rc-select/es/Select';
2427

2528
export type SelectProps<
26-
ValueType = unknown,
27-
OptionType extends DefaultOptionType | GroupedOptionType = DefaultOptionType,
28-
> = AntdSelectProps<ValueType, OptionType> & RefAttributes<BaseSelectRef>;
29+
TValue = unknown,
30+
TOption extends
31+
| OptionType<TValue>
32+
| GroupedOptionType<TValue> = OptionType<TValue>,
33+
> = AntdSelectProps<TValue, TOption> & RefAttributes<BaseSelectRef>;
2934

3035
const StyledSelect = styled(AntdSelect)`
3136
&,
@@ -54,10 +59,10 @@ const StyledDropdown = styled.div`
5459
`;
5560

5661
function SelectInner<
57-
ValueType,
58-
OptionType extends DefaultOptionType | GroupedOptionType,
62+
TValue,
63+
TOptionType extends OptionType<TValue> | GroupedOptionType<TValue>,
5964
>(
60-
{ children, dropdownRender, ...props }: SelectProps<ValueType, OptionType>,
65+
{ children, dropdownRender, ...props }: SelectProps<TValue, TOptionType>,
6166
ref: ForwardedRef<BaseSelectRef>,
6267
) {
6368
const styledDropdownRender = useCallback(
@@ -70,7 +75,7 @@ function SelectInner<
7075
);
7176

7277
return (
73-
<StyledSelect<ValueType, OptionType>
78+
<StyledSelect<TValue, TOptionType>
7479
ref={ref}
7580
dropdownRender={styledDropdownRender}
7681
{...props}
@@ -82,9 +87,11 @@ function SelectInner<
8287

8388
export const Select = forwardRef(SelectInner) as unknown as (<
8489
TValue = unknown,
85-
TOption extends DefaultOptionType | GroupedOptionType = DefaultOptionType,
90+
TOptionType extends
91+
| OptionType<TValue>
92+
| GroupedOptionType<TValue> = OptionType<TValue>,
8693
>(
87-
props: SelectProps<TValue, TOption> & RefAttributes<BaseSelectRef>,
94+
props: SelectProps<TValue, TOptionType> & RefAttributes<BaseSelectRef>,
8895
) => ReactElement) & {
8996
Option: typeof AntdSelect.Option;
9097
OptGroup: typeof AntdSelect.OptGroup;

0 commit comments

Comments
 (0)