unenum
Version:
Universal ADT utilities for TypeScript.
47 lines (46 loc) • 3.15 kB
TypeScript
import type { Identity } from "./shared/identity.js";
import type { Intersect } from "./shared/intersect.js";
export type Enum<TVariants extends Enum.Variants, TDiscriminant extends Enum.Discriminant = Enum.Discriminant.Default> = {
[TKey in keyof TVariants]-?: TVariants[TKey] extends Enum.Variants.UnitValueAny ? Enum.Variants.Unit<TKey & string, TDiscriminant> : TVariants[TKey] extends Enum.Variants.DataValueAny ? Enum.Variants.Data<TKey & string, TVariants[TKey], TDiscriminant> : never;
}[keyof TVariants];
export { is, is_ } from "./enum.is.js";
export { match, match_ } from "./enum.match.js";
export { builder, builder_ } from "./enum.builder.js";
export declare namespace Enum {
export type Any<TDiscriminant extends Discriminant = Discriminant.Default> = Record<TDiscriminant, string>;
export type Discriminant = string;
export namespace Discriminant {
type Default = "_type";
}
export type Variants = Record<Variants.KeyAny, Variants.UnitValueAny | Variants.DataValueAny>;
export namespace Variants {
type KeyAny = string;
type UnitValueAny = true;
type DataValueAny = Record<string, unknown>;
type Unit<TKey extends KeyAny, TDiscriminant extends Discriminant> = Identity<{
[TDiscriminantKey in TDiscriminant]: TKey;
}>;
type Data<TKey extends KeyAny, TData extends DataValueAny, TDiscriminant extends Discriminant> = Identity<{
[TDiscriminantKey in TDiscriminant]: TKey;
} & TData>;
}
export type Root<TEnum extends Any<TDiscriminant>, TDiscriminant extends Discriminant = Discriminant.Default> = Identity<Intersect<TEnum extends unknown ? {
[Key in TEnum[TDiscriminant]]: [
Exclude<keyof TEnum, TDiscriminant>
] extends [never] ? true : {
[Key in keyof TEnum as Key extends TDiscriminant ? never : Key]: TEnum[Key];
};
} : never>>;
export type Keys<TEnum extends Any<TDiscriminant>, TDiscriminant extends Discriminant = Discriminant.Default> = TEnum[TDiscriminant];
export type Pick<TEnum extends Any<TDiscriminant>, TKeys extends Keys<TEnum, TDiscriminant>, TDiscriminant extends Discriminant = Discriminant.Default> = Extract<TEnum, Record<TDiscriminant, TKeys>>;
export type Omit<TEnum extends Any<TDiscriminant>, TKeys extends Keys<TEnum, TDiscriminant>, TDiscriminant extends Discriminant = Discriminant.Default> = Exclude<TEnum, Record<TDiscriminant, TKeys>>;
export type Extend<TEnum extends Any<TDiscriminant>, TVariants extends Variants, TDiscriminant extends Discriminant = Discriminant.Default> = Merge<TEnum | Enum<TVariants, TDiscriminant>, TDiscriminant>;
export type Merge<TEnums extends Any<TDiscriminant>, TDiscriminant extends Discriminant = Discriminant.Default> = Enum<TrueOrObj<Intersect<TrueAsEmpty<TEnums extends unknown ? Root<TEnums, TDiscriminant> : never>>>, TDiscriminant>;
type TrueOrObj<T> = {
[K in keyof T]: keyof T[K] extends never ? true : Identity<T[K]>;
};
type TrueAsEmpty<T> = {
[K in keyof T]: T[K] extends true ? Record<never, never> : T[K];
};
export {};
}