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

如何在TypeScript中为Google Map的MVCObject、InfoWindow添加自定义属性与方法?

最优解决方案:TypeScript模块扩展 + 原型增强

在TypeScript中扩展Google Maps的内置类型和方法,推荐使用**模块扩展(Module Augmentation)**结合原型增强的方式,既保留类型检查,又不用修改node_modules,完全适配你的技术栈。

步骤1:扩展Google Maps类型声明

在项目的src/types目录下创建google-maps.d.ts文件(TypeScript会自动识别该目录下的类型声明),添加以下代码扩展MVCObject和InfoWindow的类型:

declare module 'google.maps' {
  // 为MVCObject添加id、label属性的类型定义
  interface MVCObject {
    id?: string;
    label?: string;
  }

  // 为InfoWindow添加isOpened方法的类型定义
  interface InfoWindow {
    isOpened(): boolean;
  }
}

这个文件会告诉TypeScript,google.maps.MVCObject实例允许拥有id和label属性,InfoWindow实例拥有isOpened方法,全程保留类型检查和代码提示。

步骤2:实现InfoWindow的isOpened方法

创建一个工具文件(比如src/utils/googleMapsExtensions.ts),编写方法的具体实现并挂载到原型上:

export const initGoogleMapsExtensions = () => {
  // 避免重复挂载方法
  if (google.maps.InfoWindow.prototype.isOpened) return;

  // 实现isOpened:通过map属性判断InfoWindow是否打开(打开时map不为null)
  google.maps.InfoWindow.prototype.isOpened = function () {
    return this.getMap() !== null;
  };
};

步骤3:在React组件中使用

结合@googlemaps/js-api-loader加载地图后,先初始化扩展,再创建Marker和InfoWindow:

import { Loader } from '@googlemaps/js-api-loader';
import { useEffect, useRef } from 'react';
import { initGoogleMapsExtensions } from './utils/googleMapsExtensions';

const MapComponent = () => {
  const mapRef = useRef<google.maps.Map | null>(null);

  useEffect(() => {
    const loader = new Loader({
      apiKey: '你的Google Maps API密钥',
      version: 'weekly',
    });

    loader.load().then(() => {
      // 初始化Google Maps扩展方法
      initGoogleMapsExtensions();

      // 创建地图实例
      const map = new google.maps.Map(mapRef.current!, {
        center: { lat: -34.397, lng: 150.644 },
        zoom: 8,
      });
      mapRef.current = map;

      // 创建带id、label的Marker(TypeScript会自动校验属性类型)
      const marker = new google.maps.Marker({
        position: { lat: -34.397, lng: 150.644 },
        map,
        title: 'Hello World!',
      });
      marker.id = 'marker-001';
      marker.label = '自定义标记';

      // 创建InfoWindow并使用isOpened方法
      const infoWindow = new google.maps.InfoWindow({
        content: '<div>这是自定义信息窗口</div>',
      });

      marker.addListener('click', () => {
        infoWindow.open(map, marker);
        console.log('信息窗口状态:', infoWindow.isOpened()); // 输出true
      });

      setTimeout(() => {
        infoWindow.close();
        console.log('信息窗口状态:', infoWindow.isOpened()); // 输出false
      }, 3000);
    });
  }, []);

  return <div ref={mapRef} style={{ width: '100%', height: '400px' }} />;
};

export default MapComponent;

方案优势对比

  • 对比方案1(用get/set):全程保留TypeScript类型检查,属性名写错会直接报错,代码提示更友好
  • 对比方案2(修改node_modules):自定义类型声明和扩展代码都保存在项目内,可提交到Git仓库共享,不会被npm install覆盖,维护性更强

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 01:40:03