UNPKG

mobx-keystone

Version:

A MobX powered state management solution based on data trees with first class support for TypeScript, snapshots, patches and much more

64 lines (58 loc) 1.59 kB
import { assertIsObject } from "../../utils" import type { IdentityType } from "../schemas" import { typesOr } from "../utility/typesOr" import { typesLiteral } from "./typesPrimitive" /** * @ignore * Enum like object. */ export interface EnumLike { [k: string]: number | string [v: number]: string } /** * @internal */ export function enumValues(e: EnumLike): (string | number)[] { const vals: (string | number)[] = [] for (const k of Object.keys(e)) { const v = e[k] // we have to do this since TS does something weird // to number values // Hi = 0 -> { Hi: 0, 0: "Hi" } // and SWC currently generates enum code inconsistent with TS/Babel // https://github.com/swc-project/swc/issues/3711 if (!vals.includes(v) && ((typeof v !== "string" && v !== +k) || e[v] !== +k)) { vals.push(v) } } return vals } /** * @ignore * Extract enum values out of a enum object. */ export type EnumValues<E extends EnumLike> = E extends Record<infer _K, infer V> ? V : never /** * An enum type, based on a TypeScript alike enum object. * Syntactic sugar for `types.or(...enum_values.map(types.literal))` * * Example: * ```ts * enum Color { * Red = "red", * Green = "green" * } * * const colorType = types.enum(Color) * ``` * * @template E Enum type. * @param enumObject * @returns */ export function typesEnum<E extends EnumLike>(enumObject: E): IdentityType<EnumValues<E>> { assertIsObject(enumObject, "enumObject") const literals = enumValues(enumObject).map((e) => typesLiteral(e)) return typesOr(...literals) as any }