
export type OriginName = "defaults" | "service" | "portal-item" | "web-scene" | "web-map" | "link-chart" | "user";

export interface Types<T extends Base = any, Base = T> {
  base: (new (...params: any[]) => Base) | null;
  key: string | ((obj: any) => string);
  typeMap: Record<string, new (...params: any[]) => T>;
}

/**
 * Casts a value from one type to another.
 *
 * @param value - the value.
 * @returns the cast value.
 */
export type Caster<T = any> = (value: any) => T;

export interface PropertyMetadataBase<T extends Base = any, Base = T> {
  /** The function to use to [autocast](https://developers.arcgis.com/javascript/latest/autocasting/) the property. Alternative to define the `type`. The function is called with the value set by the user and should return the cast value. */
  cast?: Caster<T> | null;
  /**
   * Indicates whether the property can be set during construction but is otherwise read-only.
   *
   * @default false
   */
  constructOnly?: boolean;
  /** Property names of dependencies. */
  dependsOn?: string[];
  /**
   * Indicates whether the property is read-only.
   *
   * @default false
   */
  readOnly?: boolean;
  /** The constructor used to [autocast](https://developers.arcgis.com/javascript/latest/autocasting/) the property. */
  type?: any;
  /** The default value for the property. */
  value?: T | null;
}

export interface InputPropertyMetadata<T extends Base = any, Base = T> extends PropertyMetadataBase<T, Base> {
  /** The property decorator that creates a two-way binding between the property it decorates and an inner property of one of its members. */
  aliasOf?: string;
}