'How can I use TypeScript for JavaScript loaded via script tag?

I'm currently bringing TypeScript into an existing Vue2/Nuxt(v2.15) project, and have ran into an issue. On one page, I bring mapbox-gl in via CDN. As it's below the fold, I lazy load this in via a script tag that is created once the document has finished loading. I use this approach for other 3rd party code elsewhere.

// helpers.ts

export const onLoad = (callback: Function, delay = 1) => {
  if (document.readyState === "complete") {
    setTimeout(() => callback(), delay);
  } else {
    window.addEventListener("load", function() {
      setTimeout(() => callback(), delay);
    })
  }
}
import {onLoad} from "./helpers";

export default ({ $config }) => {
  if ($config.environment === 'production') {
    onLoad(() => {
      const script = document.createElement('script')
      script.src = "https://api.mapbox.com/mapbox-gl-js/v2.7.0/mapbox-gl.js"
      document.getElementsByTagName('head')[0].appendChild(script)
    })
  }
}

This works well, however I'm now looking to bring TypeScript into the mix. The issue is, TypeScript doesn't recognise mapboxgl.

References to mapboxgl properties (eg. mapboxgl.accessToken) are flagged as an issue in my IDE. When I hover over to see the details of the issue, I get:

TS2304: Cannot find name 'mapboxgl'.

I've tried installing @types/mapbox-gl via. npm i @types/mapbox-gl --save-dev, but this hasn't resolved the issue. I think this approach only works if I install mapbox-gl as a dependency in the project, which I'm keen to avoid- I'd rather lazy load 3rd party code in via scripts.

So the question is, how can I use TypeScript for javascript loaded via script tag?

EDIT:

I think the suggested question/answer is helpful, but doesn't completely answer the specific question I'm asking. Declaring mapboxgl as a global variable would suppress the IDE error, but how do I then map that declaration to the types provided by @types/mapbox-gl? Also, the suggested question/answer has the title "Create a global variable in TypeScript"- not something that's likely to come up when people are searching for a solution for "How can I use TypeScript for JavaScript loaded via script tag?". I think a more focused answer could benefit others.



Solution 1:[1]

You would create a .d.ts file add it to your tsconfig.json types/typeRoots. Then you import the type of global mapboxgl object and declare it on window.

// I dont know excact type name of mapboxgl so this is an example
import {mapboxgl} from "mapboxgl";

interface Window {
  mapboxgl: mapboxgl;

  anotherCustomProperty: number;
}

Then you should be able to use window.mapboxgl in your script and it references the correct type.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Code Spirit