How to install Typescript typings for google maps

Typescript

Typescript Problem Overview


How can it be done - I've tried combinations of

typings install [googlemaps | google.maps] [--ambient] --save

and end up with variations on this error

> typings ERR! message Unable to find "googlemaps" for "npm" in the registry.

Per Amy's suggestion, I've also download to the relevant directory and added

/// <reference path="main/ambient/google.maps/google.maps.d.ts" />

to my main.d.ts (a file which is clearly being read as I don't get other errors).

And I can't find anything on the web to answer the question

My end goal is to get rid of this sort of error

>error TS2503: Cannot find namespace 'google'.

Typescript Solutions


Solution 1 - Typescript

So what makes this exceptional is that the maps script needs to be downloaded separately from your app bundle. It's not your typical npm install where you get your .js and .ts nicely packaged for consumption.

TLDR: the typings can be installed via npm but the .js script must be downloaded via a <script> tag (for SPAs this tag can be appended to your web page on-the-fly to improve initial load time of your app, which is what I do).

My recommended path is as follows:

Install

npm install --save-dev @types/googlemaps

Import

import {} from 'googlemaps';

Load & Use (this function makes sure the maps script is only appended to the page once, so that it can be called over and over)

addMapsScript() {
  if (!document.querySelectorAll(`[src="${googleMapsUrl}"]`).length) { 
    document.body.appendChild(Object.assign(
      document.createElement('script'), {
        type: 'text/javascript',
        src: googleMapsUrl,
        onload: () => doMapInitLogic()
      }));
  } else {
    this.doMapInitLogic();
  }
}

Remember, the maps script must be appended to the page and the script must be downloaded before anything else happens. If you're using Angular, for example, I wrap the addMapsScript() logic in an observable and put in my map components route resolver.

Use the types (Type definitions include, but are not limited to):

const mapRef: google.maps.Map;
const bounds: google.maps.LatLngBounds;
const latLng: google.maps.LatLng;

Get Rid of the warning:@types/googlemaps/index.d.ts' is not a module.

Add a file at your projects root directory called index.d.ts and insert the following:

declare module 'googlemaps';


Update 01.06.2018 (findings of @DicBrus):

In order to import google namespaces and get rid of annoying error "Cannot find namespace 'google'" you should ensure that you've imported namespace definitions in @types/googlemaps

There are two ways to do it:

  1. triple-slash directive

    /// Worked fine, but not so elegant.

Documentation could be found here: https://www.typescriptlang.org/docs/handbook/triple-slash-directives.html

  1. Ensure that it is imported in tsconfig.json and since it is imported you do not need to import something additionally

Detailed manual is here: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html

you should check two subsections under compilerOptions: typeRoots and types

By default all type definitions under node_modules/@types are imported unless you specified exactly what you need.

In my particular case I had following section:

"types": []

It disables automatic inclusion of @types packages.

Removing this line re-solved issue for me, as well also adding triple-slash directive helped. But I chose the second solution.

As for the "empty" import, I didn't found any explanation how and why it works. I suppose that it does NOT import any module or class, but it does import namespaces. This solution is not suitable for me, since IDE marks this import as "not used" and it can be easily removed. E.g, webstorm's command Ctrl+Alt+O - prettifies code and removes all unnecessary imports.

Solution 2 - Typescript

In practise, my use case is the Angular CLI, and there all I need is

npm install --save @types/google-maps

Solution 3 - Typescript

I tested these steps on my ionic 2 project and it is works perfectly:

  1. install typings globally :

npm install typings --global

2. install google.maps via typings


typings install dt~google.maps --global --save

3. open tsconfig.json and add "typings/*.d.ts" to your "include" array as shown below (tsconfig.json).


{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "declaration": false,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [
      "dom",
      "es2015"
    ],
    "module": "es2015",
    "moduleResolution": "node",
    "sourceMap": true,
    "target": "es5"
  },
  "include": [
    "src/**/*.ts",
    "typings/*.d.ts"
  ],
  "exclude": [
    "node_modules"
  ],
  "compileOnSave": false,
  "atom": {
    "rewriteTsconfig": false
  }
}

Solution 4 - Typescript

typings install google.maps --global

You need the --global (used to be --ambient) flag to search DefinitlyTyped

Solution 5 - Typescript

As of now the correct way to install is:

typings install dt~google.maps --global [--save]

Solution 6 - Typescript

As of typescript 2

npm install --save @types/googlemaps

Add typeroots to your tsconfig

{
  "compilerOptions": {
    "typeRoots": ["./node_modules/@types/"]
  }
}

Solution 7 - Typescript

I struggled to define the google object on the window, finally found a good way, by extending Window interface.

Just create a google-maps.d.ts file with this:

import '@types/googlemaps';

declare global {
  interface Window {
    google: typeof google;
  }
}

And add it to a directory called types at your root folder. Then point to this folder in your tsconfig.json file.

// tsconfig.json
compilerOptions: {
   ...
   "typeRoots": [
     "node_modules/@types",
     "types"
   ],
   ...
}

Solution 8 - Typescript

My solution (works for Vue2.x):

Install

npm install --save @types/googlemaps

Add script to index.html

<script src="https://maps.googleapis.com/maps/api/js?key=XXX&libraries=YYYY"></script>

Create in root folder types/index.d.ts

Put here the next lines:

/// <reference path="../node_modules/@types/googlemaps/index.d.ts" />
declare module 'googlemaps';

Open tsconfig.json and add "types/*.d.ts" to your "include" array.

  "include": [
    "src/**/*.ts",
    "src/**/*.tsx",
    "src/**/*.vue",
    "tests/**/*.ts",
    "tests/**/*.tsx",
    "types/**/*.d.ts"
  ],

Solution 9 - Typescript

The easyest way is use a triple-slash directive. Fortunately, there's an alternative syntax available which takes advantage of the standard package resolution:

 /// <reference types="googlemaps" />

Solution 10 - Typescript

Stephen Paul clearly explains everything, but there is something important to mention. tsconfigs can extend each other. And extended one can overwrite the parent one. In my case I had another tsconfig.app.json under app directory which has

types: []

arrays. As Stephen already explained this empty array overrides typeRoots. So just remove all types arrays in ALL related tsconfig files and ensure that

"typeRoots": ["node_modules/@types"]

is present. Needless to say that @types@googlemaps must be installed

Solution 11 - Typescript

For users of Angular9+ I would STRONGLY recommend using their official component

Step 1: Installation:

npm install --save-dev @angular/google-maps

Step 2: Registration

@NgModule({
  imports: [
    GoogleMapsModule
  ]
})
export class AppModule { }

Step 3: Implementation

<google-map [center]="center" [options]="options"></google-map>
center = new google.maps.LatLng(-30.5595, 22.9375);
options: google.maps.MapOptions = {
  mapTypeId: 'hybrid',
};

See https://medium.com/angular-in-depth/google-maps-is-now-an-angular-component-821ec61d2a0 for a more detailed guide

Solution 12 - Typescript

Well I have tried all the above without success in my angular 11 project, finally the official typing from google solved my issue :

npm install --save @types/google.maps

Solution 13 - Typescript

If you face the error message Cannot find namespace ‘google’ while previewing, then you need to do two things.

  1. Install Google Map plugin

    npm install @google/maps

  2. Just import the google maps to app.component.ts file

    import { google } from '@google/maps';

Source: https://medium.com/javascript-in-plain-english/integrate-google-maps-to-your-angular-application-step-by-step-guide-3604aadb76d1

Solution 14 - Typescript

The new @types/google__maps works perfectly for us. The original one(@types/googlemaps) was tricky and has many browser dependencies(like HTMLElement) which would fail the TS compiling if you use it in a nodejs environment.

>npm install @types/google__maps -D

So we have googlemaps, google-maps, and google__maps in DefinitelyTyped. The difference are explained below: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/29625#issuecomment-429207839

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSimon HView Question on Stackoverflow
Solution 1 - TypescriptStephen PaulView Answer on Stackoverflow
Solution 2 - TypescriptSimon HView Answer on Stackoverflow
Solution 3 - Typescriptuser2662006View Answer on Stackoverflow
Solution 4 - TypescriptMike JerredView Answer on Stackoverflow
Solution 5 - TypescriptMatyasView Answer on Stackoverflow
Solution 6 - TypescriptJohansrkView Answer on Stackoverflow
Solution 7 - TypescriptfelixmoshView Answer on Stackoverflow
Solution 8 - TypescriptAndrey BulgakovView Answer on Stackoverflow
Solution 9 - TypescriptÍcaro de BarrosView Answer on Stackoverflow
Solution 10 - TypescriptTimothyView Answer on Stackoverflow
Solution 11 - TypescriptStephen PaulView Answer on Stackoverflow
Solution 12 - TypescriptMoussaView Answer on Stackoverflow
Solution 13 - TypescriptRutendoView Answer on Stackoverflow
Solution 14 - TypescriptLeOn - Han LiView Answer on Stackoverflow