【问题标题】:How to import types into vue2 typescript project如何将类型导入 vue2 typescript 项目
【发布时间】:2021-08-17 14:10:13
【问题描述】:

这个 repo 是 youtube api 的类型

https://www.npmjs.com/package/@types/youtube

将这些类型导入 vue2 项目的正确方法是什么?

以下代码抱怨类型未定义。但是如果我导入类型 ts 会抱怨并说缺少依赖项。

<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>

我有一个 global.d.ts,但在这里我只能将 YT 声明为 any:

interface Window {
  YT: any
}

在 tsconfig 中:

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

但这不会自动解决:/

【问题讨论】:

    标签: typescript vue.js types


    【解决方案1】:

    类型

    无需为此在tsconfig.json 中添加typeRoots

    将类型声明文件中的类型导入为yt,并将YT: any替换为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;
      }
    }
    

    如果使用 VS Code,请确保重新启动 IDE 以便正确索引文件。

    ESLint

    配置YT 全局(如果正在运行,请重新启动您的开发服务器):

    // .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>
    

    GitHub demo

    【讨论】:

    • 感谢您的回答,但除非您在 tsconfig 中将 skipLibCheck 标记为 true,否则您提出的解决方案将不起作用。将其标记为 true 会破坏其余的应用程序类型检查。 EG 以下应该失败:``` const player = new YT.Player( document.getElementById('doesnotexist'), { events: 321, height: { a: 1 } } ); ```
    • 如果跳过 skipLibCheck 不正确,打字稿会立即再次抱怨并且不允许导入类型文件。
    • (虽然我还不知道答案:))
    猜你喜欢
    • 2017-01-23
    • 2016-10-30
    • 1970-01-01
    • 2019-02-05
    • 2016-03-12
    • 2017-11-28
    • 2020-07-20
    • 2021-03-29
    • 2023-03-15
    相关资源
    最近更新 更多