Search code examples
typescriptyoutube-apisystemjsyoutube-javascript-api

SystemJS: The YouTube API external JS library mistaken for local TypeScript module


Training my TypeScript and Angular skills. First by converting my simple HTML website's two scripts to JUST TypeScript for now. I was able to convert the Scroller script, but am having problems with YouTube API as it is an remote external JS file and not a SystemJS module.

I failed to have the API trigger a module's function after it has loaded. So here I found out that using 'await import' is supposedly the way to go, but it isn't working out.

SystemJS.config({
  map: {
	youtube: "https://www.youtube.com/iframe_api"
  },
  meta: {
	"https://www.youtube.com/iframe_api": {
	  "format": "global",
	  "exports": "youtube",
	  "scriptLoad": true,
	  "build": false
	}
  }
});

...

export default class YouTubeService {
async loadAPI() {

	try {
		await import('youtube'); // automatically injects a script tag
		console.log('API loaded');
	}
	catch (e) {
		console.error('The YouTube API failed to load');
	}

TypeScript throws the following error:

/js/main.ts [1 errors] (48, 17) File '/var/www/magia-ts/node_modules/@types/youtube/index.d.ts' is not a module.

Original source code: https://github.com/Pendrokar/magia-ts/blob/7677f0ad1e2219ac041e3a8177561c36e905c3c3/js/main.ts#L48


Solution

  • Since the YouTube API was originally designed to be loaded globally, @types/youtube describes the global YT variable that it defines. The youtube virtual module that you have configured with SystemJS and are trying to import is not declared anywhere for TypeScript. Since the name matches, TypeScript is looking for a declaration of the youtube module in @types/youtube, but it isn't there. You'll need to add a declaration that simply indicates that the youtube module is the same as the YT global variable declared by @types/youtube. Create a new file declaration.d.ts containing:

    declare module "youtube" {
        export = YT;
    }
    

    and the TypeScript error should go away.

    As an aside, shouldn't the exports in the SystemJS configuration entry be YT, not youtube?