type Method<T, R, F extends string> = ((reader: R) => T) | { [key in F]: (reader: R) => T };
export type ReadMethod<T, R> = Method<T, R, "deserialize">;
export type AsyncReadMethod<T, R> = Method<T | Promise<T>, R, "deserialize">;

export type WriteMethod<T, W> = ((writer: W, value: T) => void) | { serialize: (writer: W, value: T) => void };

export type ReadMethodReturnValue<X> = X extends ReadMethod<infer Y, any> ? (Y extends Promise<infer Z> ? Z : Y) : never;

export enum ObjectValueType {
  Object,
  Array,
  String,
  Number,
  Boolean,
  Null,
}

export type ObjectValue = { [key: string]: ObjectValue } | ObjectValue[] | null | string | number | boolean
