interface Coordinate {
  lat: string | number;
  lng: string | number;
}
interface Point {
  x: number;
  y: number;
}
interface Size {
  w: number;
  h: number;
}
interface Icon {
  url: string;
  anchor?: Point;
  labelOrigin?: Point;
  origin?: Point;

  size?: Size;
  scaledSize?: Size;
}
type GoogleMapType = google.maps.Map;
type GoogleMarkerType = google.maps.Marker;
type GoogleLatLngType = google.maps.LatLng;
type GooglePolygonType = google.maps.Polygon;
type GooglePolylineType = google.maps.Polyline;
type GoogleInfoWindow = google.maps.InfoWindow;
type GoogleOverlayViewType = google.maps.OverlayView;
type GooglePolygonOptions = google.maps.PolygonOptions;
type GoogleReadonlyIconType = google.maps.ReadonlyIcon;
type GooglePolylineOptions = google.maps.PolylineOptions;
type GoogleReadonlySymbolType = google.maps.ReadonlySymbol;
type GoogleInfoWindowOptions = google.maps.InfoWindowOptions;
type GoogleReadonlyMarkerOptions = google.maps.ReadonlyMarkerOptions;
type MarkerIcon = string | GoogleReadonlyIconType | GoogleReadonlySymbolType;
// addMarker参数的类型
interface GmapUtilMarkerOptions extends GoogleReadonlyMarkerOptions {
  lat: string | number;
  lng: string | number;
  icon: {
    url: string;
    origin?: Point;
    anchor?: Point;
    labelOrigin?: Point;
    size?: Size;
    scaledSize?: Size;
  };
}

type MarkerOrMarkerArray = GoogleMarkerType | GoogleMarkerType[];

interface GenerateGmapUtilFunctionResult {
  map: GoogleMapType;
  markers: GoogleMarkerType[];
  lines: GooglePolylineType[];
  polygons: GooglePolygonType[];
  customInfoWindows: GoogleOverlayViewType[];
  createLatLng: (opt: Coordinate) => GoogleLatLngType;
  addMarker: (opt: GmapUtilMarkerOptions) => GoogleMarkerType;
  delMarker: (marker: GoogleMarkerType) => void;
  addEvent: (
    instance: object,
    eventName: string,
    handler: (...args: any[]) => void
  ) => GenerateGmapUtilFunctionResult;
  removeEvent: (
    instance: object,
    eventName: string
  ) => GenerateGmapUtilFunctionResult;
  getIcon: (iconOpt: Icon | string) => MarkerIcon;
  searchMarkerByPosition: (pos: Coordinate) => MarkerOrMarkerArray | null;
  changeMarkerIcon: (
    marker: GoogleMarkerType,
    iconOption: Icon
  ) => GenerateGmapUtilFunctionResult;
  createInfoWindow: (
    infoWindowOption: GoogleInfoWindowOptions
  ) => GoogleInfoWindow;
  showInfoWindow: (
    infoWindow: GoogleInfoWindow,
    marker: GoogleMarkerType
  ) => GenerateGmapUtilFunctionResult;
  closeInfoWindow: (
    infoWindow: GoogleInfoWindow
  ) => GenerateGmapUtilFunctionResult;
  drawLine: (
    pos: Coordinate[],
    opt?: GooglePolylineOptions
  ) => GooglePolylineType;
  drawPolygon: (
    pos: Coordinate[],
    opt?: GooglePolygonOptions
  ) => google.maps.Polygon;
  clearPolygon: (polygon: GooglePolygonType) => void;
  fitBounds: (latlngs: Coordinate[]) => void;
  setCenter: (latlngs: Coordinate[]) => void;
  getDistance: (start: Coordinate, end: Coordinate) => number;
  getPointFromDistance: (
    latLng: Coordinate,
    angle: number,
    distance: number
  ) => Coordinate;
  getRightTopPointFromDistance: (
    distance: number,
    coord: Coordinate
  ) => Coordinate;
  getRightBottomPointFromDistance: (
    distance: number,
    coord: Coordinate
  ) => Coordinate;
  getLeftTopPointFromDistance: (
    distance: number,
    coord: Coordinate
  ) => Coordinate;
  getLeftBottomPointFromDistance: (
    distance: number,
    coord: Coordinate
  ) => Coordinate;
  createPolygonByCenter: (
    center: Coordinate,
    pathLen: number,
    distance: number,
    rorateAngle: number
  ) => Coordinate[];
  setZoom: (zoom: number) => void;
  customInfoWindow: (
    position: Coordinate,
    {
      content,
      extraClass,
    }: {
      content: string;
      extraClass?: string;
    }
  ) => void;
  [propName: string]: any;
}
