Skip to content

Commit 8ccf2a4

Browse files
committed
feat: add toSelectPlugin
1 parent 837485c commit 8ccf2a4

File tree

10 files changed

+290
-205
lines changed

10 files changed

+290
-205
lines changed
Lines changed: 130 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,140 @@
1-
import type {
2-
BuiltInLocaleKeys,
3-
EnumInit,
4-
EnumItemClass,
5-
EnumKey,
6-
EnumValue,
7-
IEnum,
8-
PluginFunc,
9-
ValueTypeFromSingleInit,
1+
import {
2+
type BuiltInLocaleKeys,
3+
type EnumInit,
4+
type EnumItemClass,
5+
type EnumKey,
6+
type EnumValue,
7+
type IEnum,
8+
type PluginFunc,
9+
type ValueTypeFromSingleInit,
1010
} from 'enum-plus';
11-
import type { StandardEnumInit } from 'lib/types';
11+
import type { StandardEnumInit, StandardEnumItemInit } from 'lib/types';
1212

13-
export type PluginOptions = Pick<ToSelectConfig<EnumInit>, 'labelField' | 'valueField'>;
13+
export type PluginOptions = Pick<ToSelectConfig<EnumInit, string, string>, 'labelField' | 'valueField'>;
1414

1515
const toSelectPlugin: PluginFunc<PluginOptions> = (options, Enum) => {
1616
const { labelField: globalLabelField, valueField: globalValueField } = options ?? {};
1717
Enum.extends({
18-
toList<FL extends string = string, FV extends string = string>(
18+
toSelect<
19+
FOV extends
20+
| ((item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => string)
21+
| string,
22+
FOL extends
23+
| ((item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => string)
24+
| string,
25+
>(
1926
this: IEnum<StandardEnumInit<string, EnumValue>, string, EnumValue>,
20-
config: ToSelectConfig<StandardEnumInit<string, EnumValue>, FL, FV, string, EnumValue> &
21-
FirstOptionConfig<FL, FV, EnumValue> = {}
22-
): SelectItem<FL, FV, EnumValue>[] {
27+
config?: ToSelectConfig<StandardEnumInit<string, EnumValue>, FOV, FOL, string, EnumValue> &
28+
FirstOptionConfig<
29+
EnumValue,
30+
FOV extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
31+
? R
32+
: FOV,
33+
FOL extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
34+
? R
35+
: FOL
36+
>
37+
): SelectItem<
38+
EnumValue,
39+
FOV extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
40+
? R
41+
: FOV,
42+
FOL extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
43+
? R
44+
: FOL
45+
>[] {
2346
const {
2447
firstOption = false,
2548
labelField = globalLabelField ?? 'label',
2649
valueField = globalValueField ?? 'value',
27-
} = config;
28-
const selectItems = this.items.map(
29-
(item) =>
30-
({
31-
[valueField]: item.value,
32-
[labelField]: item.label,
33-
}) as SelectItem<FL, FV, EnumValue>
34-
);
50+
} = config ?? {};
51+
const selectItems = this.items.map((item) => {
52+
const valueFieldName = typeof valueField === 'function' ? valueField(item) : (valueField as string);
53+
const labelFieldName = typeof labelField === 'function' ? labelField(item) : (labelField as string);
54+
return {
55+
[valueFieldName]: item.value,
56+
[labelFieldName]: item.label,
57+
} as SelectItem<
58+
EnumValue,
59+
FOV extends (...args: any[]) => infer R ? R : FOV,
60+
FOL extends (...args: any[]) => infer R ? R : FOL
61+
>;
62+
});
3563
if (firstOption) {
64+
const valueFieldName = typeof valueField === 'function' ? valueField(undefined) : (valueField as string);
65+
const labelFieldName = typeof labelField === 'function' ? labelField(undefined) : (labelField as string);
3666
if (firstOption === true) {
3767
// the first option
3868
const value = '' as EnumValue;
3969
const label = Enum.localize
4070
? Enum.localize('enum-plus.options.all' as BuiltInLocaleKeys)
4171
: 'enum-plus.options.all';
42-
return [{ [valueField]: value, [labelField]: label } as SelectItem<FL, FV, EnumValue>, ...selectItems];
72+
return [
73+
{
74+
[valueFieldName]: value,
75+
[labelFieldName]: label,
76+
},
77+
...selectItems,
78+
] as SelectItem<
79+
EnumValue,
80+
FOV extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
81+
? R
82+
: FOV,
83+
FOL extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
84+
? R
85+
: FOL
86+
>[];
4387
} else {
4488
return [
4589
{
4690
...firstOption,
47-
[labelField]: Enum.localize
48-
? Enum.localize(firstOption[labelField as FL])
49-
: firstOption[labelField as FL],
91+
[labelFieldName]: Enum.localize
92+
? Enum.localize(
93+
firstOption[
94+
labelFieldName as FOL extends (
95+
item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined
96+
) => infer R
97+
? R
98+
: FOL
99+
]
100+
)
101+
: firstOption[
102+
labelFieldName as FOL extends (
103+
item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined
104+
) => infer R
105+
? R
106+
: FOL
107+
],
50108
},
51109
...selectItems,
52-
];
110+
] as SelectItem<
111+
EnumValue,
112+
FOV extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
113+
? R
114+
: FOV,
115+
FOL extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
116+
? R
117+
: FOL
118+
>[];
53119
}
54120
} else {
55-
return selectItems;
121+
return selectItems as SelectItem<
122+
EnumValue,
123+
FOV extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
124+
? R
125+
: FOV,
126+
FOL extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
127+
? R
128+
: FOL
129+
>[] as SelectItem<
130+
EnumValue,
131+
FOV extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
132+
? R
133+
: FOV,
134+
FOL extends (item: EnumItemClass<StandardEnumItemInit<EnumValue>, string, EnumValue> | undefined) => infer R
135+
? R
136+
: FOL
137+
>[];
56138
}
57139
},
58140
});
@@ -61,8 +143,8 @@ const toSelectPlugin: PluginFunc<PluginOptions> = (options, Enum) => {
61143
/** More options for the options method */
62144
export interface ToSelectConfig<
63145
T extends EnumInit<K, V>,
64-
OV extends string | ((item: EnumItemClass<T[K], K, V>) => string) = string,
65-
OL extends string | ((item: EnumItemClass<T[K], K, V>) => string) = string,
146+
FOV extends string | ((item: EnumItemClass<T[K], K, V>) => string),
147+
FOL extends string | ((item: EnumItemClass<T[K], K, V>) => string),
66148
K extends EnumKey<T> = EnumKey<T>,
67149
V extends EnumValue = ValueTypeFromSingleInit<T[K], K>,
68150
> {
@@ -72,17 +154,17 @@ export interface ToSelectConfig<
72154
*
73155
* **CN:** 输出对象的value字段名,或者获取字段名的函数,默认为 `value`
74156
*/
75-
valueField?: OV;
157+
valueField?: FOV;
76158
/**
77159
* **EN:** The name of the label field in the output object, or a function to get the field name,
78160
* default is `label`
79161
*
80162
* **CN:** 输出对象的label字段名,或者获取字段名的函数,默认为 `label`
81163
*/
82-
labelField?: OL;
164+
labelField?: FOL;
83165
}
84166

85-
export interface FirstOptionConfig<FL extends string = string, FV extends string = string, V = EnumValue> {
167+
export interface FirstOptionConfig<V = EnumValue, FOV extends string = string, FOL extends string = string> {
86168
/**
87169
* **EN:** Add a default option at the top
88170
*
@@ -98,12 +180,12 @@ export interface FirstOptionConfig<FL extends string = string, FV extends string
98180
*
99181
* @default false
100182
*/
101-
firstOption?: boolean | SelectItem<FL, FV, V>;
183+
firstOption?: boolean | SelectItem<V, FOL, FOV>;
102184
}
103185

104186
/** Data structure of ant-design Select options */
105-
export type SelectItem<FL extends string = string, FV extends string = string, V = EnumValue> = Record<FV, V> &
106-
Record<FL, string>;
187+
export type SelectItem<V = EnumValue, FOV extends string = 'value', FOL extends string = 'label'> = Record<FOV, V> &
188+
Record<FOL, string>;
107189

108190
export default toSelectPlugin;
109191

@@ -113,26 +195,22 @@ declare module 'enum-plus-extend' {
113195
K extends EnumKey<T> = EnumKey<T>,
114196
V extends EnumValue = ValueTypeFromSingleInit<T[K], K>,
115197
> {
116-
toList(this: IEnum<T, K, V> & EnumExtension<T, K, V>): SelectItem<'label', 'value', V>[];
117-
toList<
118-
OV extends string | ((item: EnumItemClass<T[K], K, V>) => string) = string,
119-
OL extends string | ((item: EnumItemClass<T[K], K, V>) => string) = string,
198+
toSelect(this: IEnum<T, K, V> & EnumExtension<T, K, V>): SelectItem<V, 'value', 'label'>[];
199+
toSelect<
200+
FOV extends string | ((item: EnumItemClass<T[K], K, V> | undefined) => string),
201+
FOL extends string | ((item: EnumItemClass<T[K], K, V> | undefined) => string),
120202
>(
121203
this: IEnum<T, K, V> & EnumExtension<T, K, V>,
122-
config: ToSelectConfig<T, OV, OL, K, V> &
204+
config: ToSelectConfig<T, FOV, FOL, K, V> &
123205
FirstOptionConfig<
124-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
125-
OL extends (...args: any) => any ? ReturnType<OL> : OL,
126-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
127-
OV extends (...args: any) => any ? ReturnType<OV> : OV,
128-
V
206+
V,
207+
FOV extends (item: EnumItemClass<T[K], K, V> | undefined) => infer R ? R : FOV,
208+
FOL extends (item: EnumItemClass<T[K], K, V> | undefined) => infer R ? R : FOL
129209
>
130210
): SelectItem<
131-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
132-
OL extends (...args: any) => any ? ReturnType<OL> : OL,
133-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
134-
OV extends (...args: any) => any ? ReturnType<OV> : OV,
135-
V
211+
V,
212+
FOV extends (item: EnumItemClass<T[K], K, V> | undefined) => infer R ? R : FOV,
213+
FOL extends (item: EnumItemClass<T[K], K, V> | undefined) => infer R ? R : FOL
136214
>[];
137215
}
138216
}

src/enum-collection.ts

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,16 @@ import { Enum } from './enum';
33
import { EnumItemClass } from './enum-item';
44
import { EnumItemsArray } from './enum-values';
55
import type {
6-
BooleanFirstOptionConfig,
76
ColumnFilterItem,
87
EnumInit,
98
EnumItemInit,
10-
EnumItemOptionData,
119
EnumItemOptions,
1210
EnumKey,
1311
EnumValue,
1412
FindEnumKeyByValue,
1513
IEnumItems,
14+
ListItem,
1615
MenuItemOption,
17-
ObjectFirstOptionConfig,
1816
PrimitiveOf,
1917
StandardEnumItemInit,
2018
ToListConfig,
@@ -139,18 +137,30 @@ export class EnumCollectionClass<
139137
return this.items.has(keyOrValue);
140138
}
141139

142-
toList(): EnumItemOptionData<K, V>[];
143-
toList(config: ToListConfig & BooleanFirstOptionConfig<V>): EnumItemOptionData<K | '', V | ''>[];
144-
toList<FK = never, FV = never>(
145-
config: ToListConfig & ObjectFirstOptionConfig<FK, FV>
146-
): EnumItemOptionData<K | (FK extends never ? FV : FK), V | (FV extends never ? V : FV)>[];
147-
toList<FK = never, FV = never>(
148-
config?: ToListConfig & (BooleanFirstOptionConfig<V> | ObjectFirstOptionConfig<FK, FV>)
149-
): EnumItemOptionData<K | FK, V | FV>[] {
150-
return this.items.toList(config as ToListConfig & BooleanFirstOptionConfig<V>) as EnumItemOptionData<
151-
K | FK,
152-
V | FV
153-
>[];
140+
toList(): ListItem<V, 'value', 'label'>[];
141+
toList<
142+
FOV extends string | ((item: EnumItemClass<T[K], K, V>) => string),
143+
FOL extends string | ((item: EnumItemClass<T[K], K, V>) => string),
144+
>(
145+
config: ToListConfig<T, FOV, FOL, K, V>
146+
): ListItem<
147+
V,
148+
FOV extends (item: EnumItemClass<T[K], K, V>) => infer R ? R : FOV,
149+
FOL extends (item: EnumItemClass<T[K], K, V>) => infer R ? R : FOL
150+
>[];
151+
toList<
152+
FOV extends string | ((item: EnumItemClass<T[K], K, V>) => string),
153+
FOL extends string | ((item: EnumItemClass<T[K], K, V>) => string),
154+
>(
155+
config?: ToListConfig<T, FOV, FOL, K, V>
156+
):
157+
| ListItem<V, 'value', 'label'>[]
158+
| ListItem<
159+
V,
160+
FOV extends (item: EnumItemClass<T[K], K, V>) => infer R ? R : FOV,
161+
FOL extends (item: EnumItemClass<T[K], K, V>) => infer R ? R : FOL
162+
>[] {
163+
return this.items.toList(config as ToListConfig<T, FOV, FOL, K, V>);
154164
}
155165

156166
toMenu(): MenuItemOption<V>[] {

0 commit comments

Comments
 (0)