JoyEnum.ts 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import { Constructor, Registry } from '@polkadot/types/types'
  2. import { Enum } from '@polkadot/types/codec'
  3. import { EnumConstructor } from '@polkadot/types/codec/Enum'
  4. export interface ExtendedEnum<Types extends Record<string, Constructor>> extends Enum {
  5. isOfType: (type: keyof Types) => boolean
  6. asType<TypeKey extends keyof Types>(type: TypeKey): InstanceType<Types[TypeKey]>
  7. typeDefinitions: Types
  8. type: keyof Types & string // More typesafe type for the original Enum property
  9. }
  10. export interface ExtendedEnumConstructor<Types extends Record<string, Constructor> = Record<string, Constructor>>
  11. extends EnumConstructor<ExtendedEnum<Types>> {
  12. create<TypeKey extends keyof Types>(
  13. registry: Registry,
  14. typeKey: TypeKey,
  15. value: InstanceType<Types[TypeKey]>
  16. ): ExtendedEnum<Types>
  17. typeDefinitions: Types
  18. }
  19. // Helper for creating extended Enum type with TS-compatible isOfType and asType helpers
  20. export function JoyEnum<Types extends Record<string, Constructor>>(types: Types): ExtendedEnumConstructor<Types> {
  21. return class JoyEnumObject extends Enum.with(types) {
  22. static typeDefinitions = types
  23. typeDefinitions = JoyEnumObject.typeDefinitions // Non-static version
  24. public static create<TypeKey extends keyof Types>(
  25. registry: Registry,
  26. typeKey: TypeKey,
  27. value: InstanceType<Types[TypeKey]>
  28. ) {
  29. return new JoyEnumObject(registry, { [typeKey]: value })
  30. }
  31. // eslint-disable-next-line no-useless-constructor
  32. constructor(registry: Registry, value?: any, index?: number) {
  33. super(registry, value, index)
  34. }
  35. public isOfType(typeKey: keyof Types) {
  36. return this.type === typeKey
  37. }
  38. public asType<TypeKey extends keyof Types>(typeKey: TypeKey) {
  39. if (!this.isOfType(typeKey)) {
  40. throw new Error(`Enum.asType(${typeKey}) - value is not of type ${typeKey}`)
  41. }
  42. return this.value as InstanceType<Types[TypeKey]>
  43. }
  44. }
  45. }