You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript编译报错:需显式类型注解解决HTMLMarker声明导出问题

解决TypeScript构建报错:Declaration emit for this file requires using private name 'HTMLMarker'

问题原因

这个报错是因为TypeScript生成声明文件(.d.ts)时,无法正确处理函数内部定义的HTMLMarker类——该类属于函数私有作用域,TypeScript无法自动为它生成合法的声明类型,必须显式添加类型注解才能绕过这个问题。

解决方案(完全保留原有业务逻辑)

我们只需要为createHTMLMarker函数添加显式的返回类型注解,同时为类的属性、构造函数参数补充类型标注,就能让TypeScript顺利生成声明文件。

修改后的完整代码

/* @ts-ignore */
import type { OverlayView, LatLng, Map, LatLngLiteral } from '@types/google.maps';

// 定义匹配HTMLMarker类实例结构的接口
interface HTMLMarkerInstance extends OverlayView {
  anchor: { x: number; y: number };
  subscriptions: Array<{ remove: () => void }>;
  latLng: LatLng;
  element: HTMLDivElement;
  addListener(eventName: string, listener: EventListener): { remove: () => void };
  getPosition(): LatLng;
}

// 定义类的构造函数类型
type HTMLMarkerConstructor = new (props: {
  position: LatLngLiteral | LatLng;
  map: Map;
  className: string;
  anchor?: { x: number; y: number };
}) => HTMLMarkerInstance;

const createHTMLMarker = (google: typeof window.google): HTMLMarkerConstructor => {
  class HTMLMarker extends google.maps.OverlayView implements HTMLMarkerInstance {
    anchor: { x: number; y: number };
    subscriptions: Array<{ remove: () => void }>;
    latLng: LatLng;
    element: HTMLDivElement;

    constructor({
      position,
      map,
      className,
      anchor = { x: 0, y: 0 },
    }: {
      position: LatLngLiteral | LatLng;
      map: Map;
      className: string;
      anchor?: { x: number; y: number };
    }) {
      super();

      this.anchor = anchor;
      this.subscriptions = [];
      this.latLng = new google.maps.LatLng(position);

      this.element = document.createElement('div');
      this.element.className = className;
      this.element.style.position = 'absolute';
      this.element.style.whiteSpace = 'nowrap';

      this.setMap(map);
    }

    onAdd() {
      if (this.getPanes()) {
        this.getPanes().overlayMouseTarget.appendChild(this.element);
      }
    }

    draw() {
      if (this.getProjection()) {
        const position = this.getProjection().fromLatLngToDivPixel(this.latLng);

        const offsetX = this.anchor.x + this.element.offsetWidth / 2;
        const offsetY = this.anchor.y + this.element.offsetHeight;

        this.element.style.left = `${Math.round(position.x - offsetX)}px`;
        this.element.style.top = `${Math.round(position.y - offsetY)}px`;
        this.element.style.zIndex = parseInt(this.element.style.top, 10);
      }
    }

    onRemove() {
      if (this.element && this.element.parentNode) {
        this.element.parentNode.removeChild(this.element);
        this.subscriptions.forEach(sub => sub.remove());
        delete this.element;
        this.subscriptions = [];
      }
    }

    addListener(eventName: string, listener: EventListener) {
      const subscription = {
        remove: () => {
          this.element.removeEventListener(eventName, listener);
          this.subscriptions = this.subscriptions.filter(item => item !== subscription);
        },
      };

      this.element.addEventListener(eventName, listener);
      this.subscriptions = this.subscriptions.concat(subscription);

      return subscription;
    }

    getPosition() {
      return this.latLng;
    }
  }

  return HTMLMarker;
};

export default createHTMLMarker;

核心修改说明

  1. 添加类型接口与构造函数类型:定义HTMLMarkerInstance描述类实例的结构,HTMLMarkerConstructor描述类的构造函数类型,让TypeScript明确返回值的类型。
  2. 为函数标注返回类型:将createHTMLMarker的返回类型设为HTMLMarkerConstructor,解决私有类无法生成声明的问题。
  3. 补充类属性与参数的类型注解:为类的成员属性、构造函数参数添加明确的类型标注,消除TypeScript的类型推断歧义,确保声明文件生成正常。

如果你的项目还没有安装Google Maps的类型定义包,先执行以下命令安装:

npm install @types/google.maps --save-dev

内容的提问来源于stack exchange,提问作者Val

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:25:31