UNPKG

enum-plus

Version:

A drop-in replacement for native enum. Like native enum but much better!

102 lines (101 loc) 6.77 kB
import type { EnumLocaleExtends } from 'enum-plus/extension'; export type { LocalizeInterface } from './localize-interface'; export type EnumItemLabel = EnumLocaleExtends['LocaleKeys'] & NonNullable<string>; export type EnumInit<K extends keyof any = string, V extends EnumValue = EnumValue> = NumberEnumInit<K> | StringEnumInit<K> | StringNumberEnumInit<K> | BooleanEnumInit<K> | DateEnumInit<K> | RegExpEnumInit<K> | StandardEnumInit<K, V> | ValueOnlyEnumInit<K, V> | LabelOnlyEnumInit<K> | MetaOnlyEnumInit<K> | CompactEnumInit<K> | OmitEnumInit<K>; export type NumberEnumInit<K extends keyof any> = Record<K, number>; export type StringEnumInit<K extends keyof any> = Record<K, string>; export type StringNumberEnumInit<K extends keyof any> = Record<K, string | number>; export type BooleanEnumInit<K extends keyof any> = Record<K, boolean>; export type DateEnumInit<K extends keyof any> = Record<K, Date>; export type RegExpEnumInit<K extends keyof any> = Record<K, RegExp>; export type StandardEnumInit<K extends keyof any, V extends EnumValue> = Record<K, StandardEnumItemInit<V>>; export type ValueOnlyEnumInit<K extends keyof any, V extends EnumValue> = Record<K, ValueOnlyEnumItemInit<V>>; export type LabelOnlyEnumInit<K extends keyof any> = Record<K, LabelOnlyEnumItemInit>; export type MetaOnlyEnumInit<K extends keyof any> = Record<K, MetaOnlyEnumItemInit>; export type CompactEnumInit<K extends keyof any> = Record<K, CompactEnumItemInit>; export type OmitEnumInit<K extends keyof any> = Record<K, undefined>; export type EnumItemInit<V extends EnumValue = EnumValue> = EnumValue | StandardEnumItemInit<V> | ValueOnlyEnumItemInit<V> | LabelOnlyEnumItemInit | MetaOnlyEnumItemInit | CompactEnumItemInit | undefined; export interface StandardEnumItemInit<V extends EnumValue> { value: V; label: EnumItemLabel; } export interface ValueOnlyEnumItemInit<V extends EnumValue> { value: V; label?: never; } export interface LabelOnlyEnumItemInit { label: EnumItemLabel; value?: never; } export interface MetaOnlyEnumItemInit { value?: never; label?: never; [meta: string]: unknown; } export type CompactEnumItemInit = Record<string, never>; /** * - **EN:** Data structure of enumeration item options, used in `toList` method * - **CN:** 枚举项选项的数据结构,用于`toList`方法 * * @template V Value type of the enumeration item | 枚举项的值类型 * @template FOL Field name of the label, default is `label` | 标签字段名,默认为 `label` * @template FOV Field name of the value, default is `value` | 值字段名,默认为 `value` */ export type ListItem<V extends EnumValue = EnumValue, FOV extends string = 'value', FOL extends string = 'label', R extends Record<string, unknown> = never> = Record<FOV, V> & Record<FOL, string> & (IsNever<R> extends true ? {} : R); /** Enum value type, support number, string, symbol */ export type EnumValue = keyof any | bigint | boolean | Date | RegExp; /** Enum key collection */ export type EnumKey<T> = keyof T; /** Infer the value type from the initialization object of the enumeration item */ export type ValueTypeFromSingleInit<T, Key = string, Fallback = Key> = T extends EnumValue ? T : T extends StandardEnumItemInit<infer V> ? V : T extends ValueOnlyEnumItemInit<infer V> ? V : T extends LabelOnlyEnumItemInit ? Key : T extends MetaOnlyEnumItemInit ? Key : T extends CompactEnumItemInit ? Key : T extends undefined ? Fallback : never; /** Infer the value type from the initialization object of the enumeration collection */ export type ValueTypeFromEnumInit<T, K extends EnumKey<T> = EnumKey<T>> = T extends NumberEnumInit<K> ? number : T extends StringEnumInit<K> ? string : T extends BooleanEnumInit<K> ? string : T extends StringNumberEnumInit<K> ? string | number : T extends StandardEnumInit<K, infer V> ? V : T extends ValueOnlyEnumInit<K, infer V> ? V : T extends LabelOnlyEnumInit<K> ? K : T extends MetaOnlyEnumInit<K> ? K : T extends CompactEnumInit<K> ? K : T extends OmitEnumInit<K> ? K : K; /** * - **EN:** Find the key of the enumeration item by value * - **CN:** 通过值查找枚举项的key * * @template T Enum collection initialization data type | 枚举集合初始化数据的类型 * @template V Enum value type | 枚举值的类型 */ export type FindEnumKeyByValue<T, V extends EnumValue> = { [K in keyof T]: T[K] extends V ? K : T[K]['value'] extends V ? K : object extends T[K] ? K extends V ? K : never : undefined extends T[K] ? K extends V ? K : never : never; }[keyof T]; /** * - **EN:** Find the label of the enumeration item by value * - **CN:** 通过值查找枚举项的label显示名称 * * @template T Enum collection initialization data type | 枚举集合初始化数据的类型 * @template V Enum value type | 枚举值的类型 */ export type FindLabelByValue<T, V extends EnumValue, RAW = T[FindEnumKeyByValue<T, V>]> = RAW extends { label: unknown; } ? string : FindEnumKeyByValue<T, V>; /** * - **EN:** Find the value of the enumeration item by key * - **CN:** 通过key查找枚举项的值 * * @template T Enum collection initialization data type | 枚举集合初始化数据的类型 * @template K Enum key type | 枚举key的类型 */ export type FindValueByKey<T, K extends EnumKey<T>> = T[K] extends EnumValue ? T[K] : T[K] extends StandardEnumItemInit<infer V> ? V : T[K] extends ValueOnlyEnumItemInit<infer V> ? V : T[K] extends LabelOnlyEnumItemInit ? K : T[K] extends MetaOnlyEnumItemInit ? K : T[K] extends CompactEnumItemInit ? K : T[K] extends undefined ? K : never; export type FindKeyByMeta<T, MK extends keyof T[keyof T], MV> = { [K in keyof T]: T[K] extends Record<MK, MV> ? K : never; }[keyof T]; export type FindValueByMeta<T, MK extends keyof T[keyof T], MV> = { [K in keyof T]: T[K] extends Record<MK, MV> ? T[K][MK] : never; }[keyof T]; export type PrimitiveOf<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T extends bigint ? bigint : T extends symbol ? symbol : T extends undefined ? undefined : T extends null ? null : never; /** * - **EN:** Convert an array of objects to a Map-like object, where the key is the `key` field of the * object, and the value is the `value` field of the object * - **CN:** 将对象数组转换为类似Map的对象,其中key为对象的`key`字段,value为对象的`value`字段 * * @template A Array type | 数组类型 */ export type ArrayToMap<A extends Record<string, any>[] | readonly Record<string, any>[]> = { [K in A[number]['key']]: Extract<A[number], { key?: K; }>; }; export type ExactEqual<A, B> = [A] extends [B] ? ([B] extends [A] ? true : false) : false; export type IsNever<T> = [T] extends [never] ? true : false;