Reputation:
This repo is the types for the youtube api
https://www.npmjs.com/package/@types/youtube
What is the proper way to import these types into a vue2 project?
The following code complains as the type is not defined. But if i import the type ts complains and says missing dependency.
<template>
<div ref="ytplayer" class="MYouTube"></div>
</template>
<style lang="scss" scoped>
.MYouTube {
position: relative;
margin: 0 auto;
padding-bottom: 56.25%;
.iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
}
}
</style>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import getYoutubeId from '@/utils/getYoutubeId';
import reframe from '@/utils/reframe';
import injectScript from '@/utils/injectScript';
@Component
export default class MYouTube extends Vue {
@Prop({ required: true })
url!: string;
vidId = '';
$refs!: {
ytplayer: any
};
created () {
const vidId = getYoutubeId(this.url);
if (vidId) {
this.vidId = vidId;
}
injectScript('https://www.youtube.com/iframe_api', () => {
this.injectAndPlay();
});
}
injectAndPlay () {
new YT.Player(this.$refs.ytplayer, {
videoId: this.vidId,
playerVars: {
'playsinline': 1
},
events: {
'onReady': (event) => {
event.target.playVideo();
reframe(this.$refs.ytplayer);
},
'onStateChange': () => {
console.log('do something');
}
}
});
}
}
</script>
I have a global.d.ts but in here I can only declare YT as any:
interface Window {
YT: any
}
In the tsconfig:
"typeRoots": [
"node_modules/@types"
],
but this does not auto resolve :/
Upvotes: 0
Views: 463
Reputation: 138226
No need to add a typeRoots
in tsconfig.json
for this.
Import the types in the type declarations file as yt
, and replace YT: any
with YT: yt
:
// global.d.ts
import yt from '@types/youtube'
// `yt` needs to be outside of `global` for some reason
interface Window {
YT: yt;
}
declare global {
interface Window {
onYouTubeIframeAPIReady?: () => void;
}
}
If using VS Code, make sure to restart the IDE so that the file is properly indexed.
Configure the YT
global (and restart your dev server if running):
// .eslintrc.js
module.exports = {
globals: {
YT: true,
},
}
<template>
<div>
<div ref="ytplayer"></div>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
@Component
export default class extends Vue {
vidId = 'M7lc1UVf-VE'
mounted(): void {
window.onYouTubeIframeAPIReady = () => {
new YT.Player(this.$refs.ytplayer as HTMLElement, {
videoId: this.vidId,
playerVars: {
playsinline: 1
},
events: {
onReady(event: YT.PlayerEvent) {
event.target?.playVideo()
},
onStateChange() {
console.log('do something')
}
}
})
delete window.onYouTubeIframeAPIReady
}
const script = document.createElement('script')
script.src = 'https://www.youtube.com/iframe_api'
const firstScriptTag = document.getElementsByTagName('script')[0]
firstScriptTag.parentNode?.insertBefore(script, firstScriptTag)
}
}
</script>
Upvotes: 1