Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

建议:关于APlayer相关接口类型检查报错 #357

Open
SwingCosmic opened this issue Jan 30, 2020 · 0 comments
Open

建议:关于APlayer相关接口类型检查报错 #357

SwingCosmic opened this issue Jan 30, 2020 · 0 comments

Comments

@SwingCosmic
Copy link

问题

我有一个组件按照官方文档使用SFC+ts+vue-class-component写的:

import { APlayer } from "@moefe/vue-aplayer";
// ... 组件声明
    @Ref()
    player!: APlayer;
    audio: APlayer.Audio = {
        // ...
    };

编译能通过,但是编辑器audio类型检查(以及编译类型检查)报错

Cannot find namespace 'APlayer'

检查发现APlayer.Audio的类型定义在'@moefe/vue-aplayer/types/aplayer',我import了一下,类型检查通过,但是cli编译报错

This dependency was not found:
@moefe/vue-aplayer/types/aplayer in ...

对于webpack来说,从一个非入口.d.ts文件import任何内容都是无法编译的,因为根本不存在对应的模块,我引用ElementUI的时候就吃了很多亏。
相反,从入口声明文件import 接口是允许的,因为入口声明文件对应的模块存在,而进入babel-loader的时候,会跳过所有的类型检查,无视接口导入。

项目内的临时解决方案

在不改动npm包源码的情况下,要让代码工作通常只有3个方法:

  1. 使用jsdoc注释并包含ts专属的import,但对ts无效
  2. tsconfig.json中手动引入类型定义,下面这些都是这个问题
{
  "compilerOptions": {
    "types": [
      "webpack-env",
      "@types/jest",
      "vue-tsx-support/enable-check",
      "vue-tsx-support/options/allow-unknown-props",
      "@moefe/vue-aplayer/types/aplayer"
    ]
}
  1. 定义一个新的type,从原始导入计算出正确的类型。同样由于是类型定义,没有使用import,不会被webpack处理。
type __APlayer_Type_Import__ = typeof import("@moefe/vue-aplayer/types/aplayer");

由于aplayer.d.ts用了declare global的方式,只需要包含类型引入,不必关心实际导入的类型。

建议

为了让这些类型定义可以正确的使用,建议修改声明文件的编写方式,可以参考vue的写法。
我个人推荐的使用方式是:

  1. aplayer.d.ts去除declare global 以及namespace,直接导出所有接口
  2. index.d.ts中导入所有接口,并重新export,这样这些接口可以单独import
  3. 同时为了照顾原有代码,定义namespace APlayer包含这些接口,然后导出namespace,此时导出APlayer既是class也是namespace
import * as APlayerType from "./aplayer";
export * from "./aplayer";
export as namespace APlayer;
export class APlayer extends Vue.Component<APlayerType.Options, APlayerType.Events> {
    // ...
}
  1. 使用(经过测试通过)
import { APlayer, Audio, LrcType } from "@moefe/vue-aplayer"; 
player!: APlayer; // OK
audio1: APlayer.Audio = { }; // 可以按原来的方法用
audio2: Audio = { }; // 也可以直接用

稍后提交pr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant