@@ -5,7 +5,10 @@ import type {
55 EnumKey ,
66 EnumValue ,
77 FindEnumKeyByValue ,
8+ FindKeyByMeta ,
89 FindLabelByValue ,
10+ FindValueByKey ,
11+ FindValueByMeta ,
912 ListItem ,
1013 MenuItemOption ,
1114 PrimitiveOf ,
@@ -26,7 +29,7 @@ import { IS_ENUM_ITEMS } from './utils';
2629 * @implements {IEnumValues<T, K, V>}
2730 */
2831export class EnumItemsArray <
29- T extends EnumInit < K , V > ,
32+ const T extends EnumInit < K , V > ,
3033 K extends EnumKey < T > = EnumKey < T > ,
3134 V extends EnumValue = ValueTypeFromSingleInit < T [ K ] , K > ,
3235 >
@@ -127,6 +130,32 @@ export class EnumItemsArray<
127130 return this . some ( ( i ) => i . value === keyOrValue || i . key === keyOrValue ) ;
128131 }
129132
133+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
134+ find : IEnumItems < T , K , V > [ 'find' ] = ( fieldOrPredicate : any , valueOrThis ?: EnumValue | any ) : any => {
135+ if ( typeof fieldOrPredicate === 'function' ) {
136+ const predicate = fieldOrPredicate ;
137+ const thisArg = valueOrThis ;
138+ // If the first argument is a function, use it as a predicate
139+ return Array . prototype . find . call ( this , predicate , thisArg ) ;
140+ } else {
141+ // Otherwise, treat it as a field name and value
142+ const field : string = fieldOrPredicate ;
143+ const value = valueOrThis ;
144+ return Array . prototype . find . call ( this , ( item ) => {
145+ if ( field === 'key' || field === 'value' ) {
146+ return item [ field ] === value ;
147+ } else if ( field === 'label' ) {
148+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
149+ return ( item . raw as any ) ?. label === value || item . label === value ;
150+ } else {
151+ // For other fields, use the raw object to find
152+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
153+ return ( item . raw as any ) ?. [ field ] === value ;
154+ }
155+ } ) ;
156+ }
157+ } ;
158+
130159 toList ( ) : ListItem < V , 'value' , 'label' > [ ] ;
131160 toList <
132161 FOV extends string | ( ( item : EnumItemClass < T [ K ] , K , V > ) => string ) ,
@@ -341,6 +370,48 @@ export interface IEnumItems<
341370 */
342371 has ( keyOrValue ?: string | V ) : boolean ;
343372
373+ /**
374+ * **EN:** Find an enumeration item by key or value, or by custom meta fields
375+ *
376+ * **CN:** 通过key或value查找枚举项,或通过自定义元字段查找
377+ *
378+ * @param field The field to search by | 要查找的字段
379+ * @param value The value to search | 要查找的值
380+ *
381+ * @returns The found enumeration item or undefined if not found | 找到的枚举项,如果未找到则返回 undefined
382+ */
383+ find < FK extends 'key' | 'value' | 'label' | Exclude < keyof T [ keyof T ] , 'key' | 'value' | 'label' > , FV > (
384+ field : FK ,
385+ value : FV
386+ ) : FK extends 'key'
387+ ? FV extends K
388+ ? // @ts -expect-error: because the type infer is not clever enough, FV here should be one of K
389+ EnumItemClass < T [ FV ] , FV , FindValueByKey < T , FV > >
390+ : EnumItemClass < T [ K ] , K , V > | undefined
391+ : FK extends 'value'
392+ ? FV extends V
393+ ? // @ts -expect-error: because the type infer is not clever enough, FV here should be one of V
394+ EnumItemClass < T [ FindEnumKeyByValue < T , FV > ] , FindEnumKeyByValue < T , FV > , FV >
395+ : EnumItemClass < T [ K ] , K , V > | undefined
396+ : FK extends 'label'
397+ ? EnumItemClass < T [ K ] , K , V > | undefined
398+ : // @ts -expect-error: because the type infer is not clever enough, FK here should be one of keyof Raw
399+ FV extends T [ keyof T ] [ FK ]
400+ ? // @ts -expect-error: because the type infer is not clever enough, FV here should be one of T[keyof T][FK]
401+ EnumItemClass < T [ FindKeyByMeta < T , FK , FV > ] , FindKeyByMeta < T , FK , FV > , FindValueByMeta < T , FK , FV > >
402+ : EnumItemClass < T [ K ] , K , V > | undefined ;
403+ // Copy the Array.find type definition and extend another override
404+ find < S extends EnumItemClass < T [ K ] , K , V > > (
405+ predicate : ( value : EnumItemClass < T [ K ] , K , V > , index : number , obj : EnumItemClass < T [ K ] , K , V > [ ] ) => value is S ,
406+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
407+ thisArg ?: any
408+ ) : S | undefined ;
409+ find (
410+ predicate : ( value : EnumItemClass < T [ K ] , K , V > , index : number , obj : EnumItemClass < T [ K ] , K , V > [ ] ) => unknown ,
411+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
412+ thisArg ?: any
413+ ) : EnumItemClass < T [ K ] , K , V > | undefined ;
414+
344415 /**
345416 * - **EN:** Generate an object array containing all enumeration items
346417 * - **CN:** 生成一个对象数组,包含所有的枚举项
0 commit comments