@@ -43,22 +43,27 @@ import { SelectTopActions } from "./SelectTopActions"
43
43
import type { SelectItemObject , SelectItemProps } from "./types"
44
44
export * from "./types"
45
45
46
+ // Helper type to resolve the actual record type
47
+ export type ResolvedRecordType < R > = R extends RecordType ? R : RecordType
48
+
46
49
/**
47
50
* Select component for choosing from a list of options.
48
51
*
49
52
* @template T - The type of the emitted value
50
53
* @template R - The type of the record/item data (used with data source)
51
54
*
52
55
*/
53
- export type SelectProps < T extends string , R extends RecordType = RecordType > = {
56
+ export type SelectProps < T extends string , R = unknown > = {
54
57
onChange : (
55
58
value : T ,
56
- originalItem ?: R ,
57
- option ?: SelectItemObject < T , R >
59
+ originalItem ?: ResolvedRecordType < R > ,
60
+ option ?: SelectItemObject < T , ResolvedRecordType < R > >
61
+ ) => void
62
+ onChangeSelectedOption ?: (
63
+ option : SelectItemObject < T , ResolvedRecordType < R > >
58
64
) => void
59
- onChangeSelectedOption ?: ( option : SelectItemObject < T , R > ) => void
60
65
value ?: T
61
- defaultItem ?: SelectItemObject < T , R >
66
+ defaultItem ?: SelectItemObject < T , ResolvedRecordType < R > >
62
67
children ?: React . ReactNode
63
68
open ?: boolean
64
69
showSearchBox ?: boolean
@@ -73,18 +78,20 @@ export type SelectProps<T extends string, R extends RecordType = RecordType> = {
73
78
} & (
74
79
| {
75
80
source : DataSourceDefinition <
76
- R ,
81
+ ResolvedRecordType < R > ,
77
82
FiltersDefinition ,
78
83
SortingsDefinition ,
79
- GroupingDefinition < R >
84
+ GroupingDefinition < ResolvedRecordType < R > >
80
85
>
81
- mapOptions : ( item : R ) => SelectItemProps < T , R >
86
+ mapOptions : (
87
+ item : ResolvedRecordType < R >
88
+ ) => SelectItemProps < T , ResolvedRecordType < R > >
82
89
options ?: never
83
90
}
84
91
| {
85
92
source ?: never
86
93
mapOptions ?: never
87
- options : SelectItemProps < T , R > [ ]
94
+ options : SelectItemProps < T , ResolvedRecordType < R > > [ ]
88
95
}
89
96
) &
90
97
Pick <
@@ -154,7 +161,7 @@ const SelectValue = forwardRef<
154
161
155
162
const SelectComponent = forwardRef ( function Select <
156
163
T extends string ,
157
- R extends RecordType = RecordType ,
164
+ R = unknown ,
158
165
> (
159
166
{
160
167
placeholder,
@@ -189,6 +196,7 @@ const SelectComponent = forwardRef(function Select<
189
196
} : SelectProps < T , R > ,
190
197
ref : React . ForwardedRef < HTMLButtonElement >
191
198
) {
199
+ type ActualRecordType = ResolvedRecordType < R >
192
200
const searchInputRef = useRef < HTMLInputElement > ( null )
193
201
194
202
const [ openLocal , setOpenLocal ] = useState ( open )
@@ -212,20 +220,23 @@ const SelectComponent = forwardRef(function Select<
212
220
return {
213
221
...source ,
214
222
dataAdapter : source
215
- ? ( source . dataAdapter as PaginatedDataAdapter < R , FiltersDefinition > )
223
+ ? ( source . dataAdapter as PaginatedDataAdapter <
224
+ ActualRecordType ,
225
+ FiltersDefinition
226
+ > )
216
227
: {
217
228
fetchData : ( {
218
229
search,
219
230
} : BaseFetchOptions < FiltersDefinition > ) : PromiseOrObservable <
220
- BaseResponse < R >
231
+ BaseResponse < ActualRecordType >
221
232
> => {
222
233
return {
223
234
records : options . filter (
224
235
( option ) =>
225
236
option . type === "separator" ||
226
237
! search ||
227
238
option . label . toLowerCase ( ) . includes ( search . toLowerCase ( ) )
228
- ) as unknown as R [ ] ,
239
+ ) as unknown as ActualRecordType [ ] ,
229
240
}
230
241
} ,
231
242
} ,
@@ -246,29 +257,29 @@ const SelectComponent = forwardRef(function Select<
246
257
)
247
258
248
259
/**
249
- * Maps an item to a SelectItemProps<T, R >
260
+ * Maps an item to a SelectItemProps<T, ActualRecordType >
250
261
*/
251
262
const optionMapper = useCallback (
252
- ( item : R ) : SelectItemProps < T , R > => {
263
+ ( item : ActualRecordType ) : SelectItemProps < T , ActualRecordType > => {
253
264
if ( source ) {
254
265
if ( ! mapOptions ) {
255
266
throw new Error ( "mapOptions is required when using a source" )
256
267
}
257
268
return mapOptions ( item )
258
269
}
259
- // At this point, we are sure that options is an array of SelectItemProps<T, R >
260
- return item as unknown as SelectItemProps < T , R >
270
+ // At this point, we are sure that options is an array of SelectItemProps<T, ActualRecordType >
271
+ return item as unknown as SelectItemProps < T , ActualRecordType >
261
272
} ,
262
273
[ mapOptions , source ]
263
274
)
264
275
265
276
const { data, isInitialLoading, loadMore, isLoadingMore } =
266
- useData < R > ( localSource )
277
+ useData < ActualRecordType > ( localSource )
267
278
268
279
const { currentSearch, setCurrentSearch } = localSource
269
280
270
281
const [ selectedOption , setSelectedOption ] = useState <
271
- SelectItemObject < T , R > | undefined
282
+ SelectItemObject < T , ActualRecordType > | undefined
272
283
> ( undefined )
273
284
274
285
/**
@@ -277,7 +288,9 @@ const SelectComponent = forwardRef(function Select<
277
288
* @returns The option if found, undefined otherwise
278
289
*/
279
290
const findOption = useCallback (
280
- ( value : string | T | undefined ) : SelectItemObject < T , R > | undefined => {
291
+ (
292
+ value : string | T | undefined
293
+ ) : SelectItemObject < T , ActualRecordType > | undefined => {
281
294
if ( value === undefined ) {
282
295
return undefined
283
296
}
@@ -351,7 +364,9 @@ const SelectComponent = forwardRef(function Select<
351
364
)
352
365
353
366
const getItems = useCallback (
354
- ( records : WithGroupId < R > [ ] | R [ ] ) : VirtualItem [ ] => {
367
+ (
368
+ records : WithGroupId < ActualRecordType > [ ] | ActualRecordType [ ]
369
+ ) : VirtualItem [ ] => {
355
370
return records . map ( ( option , index ) => {
356
371
const mappedOption = optionMapper ( option )
357
372
return mappedOption . type === "separator"
@@ -519,7 +534,7 @@ const SelectComponent = forwardRef(function Select<
519
534
520
535
export const Select = SelectComponent as <
521
536
T extends string = string ,
522
- R extends RecordType = RecordType ,
537
+ R = unknown ,
523
538
> (
524
539
props : SelectProps < T , R > & { ref ?: React . Ref < HTMLButtonElement > }
525
540
) => React . ReactElement
0 commit comments