首页 > 解决方案 > 打字稿发出的声明找不到全局接口的名称

问题描述

此问题在私有 CDN 库中。我想生成 TypeScript 声明文件以供集成库的应用程序开发使用。我的问题是我生成的声明文件在正确定义的全局接口方面存在“找不到名称”错误。

首先,CDN 库的编译器选项有emitDeclarationOnlydeclarationtrue。这正确地将声明放入目录“类型”中。

 "compilerOptions": {
    "module": "es2020",
    "target": "es2020",
    "sourceMap": true,
    "checkJs": true,
    "allowJs": true,
    "emitDeclarationOnly": true,
    "declaration": true,
    "outDir": "types"

    // .... paths etc. omitted
  }

其次,我有一个全局接口声明文件,它声明了大约 7 或 8 个不同的接口。

// global.ts
    interface ComponentToggle {
        component: HTMLElement,

        // other properties here
    }

    // more interfaces here

第三,原始的 JavaScript 源文件能够使用 JSDocs 中的全局接口。这些文件使用 JSDocs 来定义它们的 TypeScript 信息。他们编译成.d.ts文件没有任何错误。

// otherfile.js
    /** Removes active state from all options.
     *
     * @param toggle {ComponentToggle} the parent element toggle message
     */
    inactivate( { component } ) {
        if ( component.contains( this ) ) {
            this.getOptions( true ).forEach( option => option.inactivate() );
        }
    }

生成的 d.ts 文件都是正确的。

// global.d.ts
    interface ComponentToggle {
        component: HTMLElement,

        // identical to the ts file
    }

// otherfile.d.ts
    /** Removes active state from all options.
     *
     * @param toggle {ComponentToggle} the parent element toggle message
     */
    inactivate({ component }: ComponentToggle): void;

现在我们解决问题。尝试使用otherfile.d.ts时,出现新的 TypeScript 错误:

TS2304: Cannot find name 'ComponentToggle'.

谁能解释发生了什么?ComponentToggle当它实际上只是用于生成这个文件时,这里怎么找不到全局接口?

编辑:主要是,当我打开受影响的 d.ts 文件时,我注意到有一个问题,因为 WebStorm 解析器会标记它们。

根据要求,这是我用来测试它的应用程序的 tsconfig,它也不是 TypeScript 应用程序。我不拥有任何将使用此库的应用程序的所有权。因为这是供 CDN 使用的,所以在源代码中使用以 /xxxyyy/ 开头的本地路径(见下文)定义了该库,这些路径在 Webpack 中被定义为“外部”,在 Karma 中也被定义为代理路径。构建(减号tsc)和单元测试运行良好,并且正确找到了库的类型。WebStorm 正确显示不存在此问题的文件的类型和提示,并且运行tsc输出与我打开文件时 WebStorm 显示的完全相同的错误。

消费应用:

{
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "ci-output",
    "unitTest",
    "tutorials",
    "lib"
  ],
  "compilerOptions": {
    "module": "es2020",
    "target": "es2020",
    "sourceMap": true,
    "checkJs": true,
    "allowJs": true,
    "emitDeclarationOnly": true,
    "declaration": true,
    "outDir": "types",
    "downlevelIteration": true,
    "baseUrl": ".",
    "paths": {
      "*": [ "AppMain", "./src/component/app-main.js" ],
      "/xxxyyy/libraryname.min.js": [ "libraryname", "./node_modules/@xxxyyy/libraryname/types/index.d.ts" ],
      "/xxxyyy/libraryname.js": [ "libraryname", "./node_modules/@xxxyyy/libraryname/types/index.d.ts" ]
    }
  }
}

图书馆本身:

{
  "include": [
    "src/**/*"
  ],
  "exclude": [
    "node_modules",
    "ci-output",
    "conf",
    "jsdocTemplate",
    "unitTest",
    "tutorials"
  ],
  "compilerOptions": {
    "module": "es2020",
    "target": "es2020",
    "sourceMap": true,
    "checkJs": true,
    "allowJs": true,
    "emitDeclarationOnly": true,
    "declaration": true,
    "outDir": "types",
    "baseUrl": "./",
    "paths": {
      "*": [ "MainComponent", "./src/component/MainComponent.js" ]
    }
  }
}

编辑 2 好的,因为似乎没有人对我有任何答案,我会尝试另一种方法。这些全局变量中的每一个都符合以下类别之一:

  1. 一个“polyfill”,因为 TypeScript 的 Window 内置定义缺少一些东西。
  1. 一些函数期望作为对象参数接收的定义。

可以做些什么来满足不涉及创建 global.ts 文件的要求 #1 和 #2?

如果没有,我如何让生成的 global.d.ts 文件被 WebStorm 和应用程序使用?我是否在“paths”、“types”、“typeRoots”或其他我还没有听说过的东西中设置配置?

此外,关于这个问题的评论似乎假设我知道一些事情。我对 TypeScript 一无所知。我很可能在这里犯了最初学者的错误。

标签: typescript

解决方案


我希望有人有比这更好的答案。我不太喜欢这种解决方案,因为它使消费应用程序必须将有关我的图书馆的信息放在他们的tsconfig.

我挖了大约一千个地方。最终,我发现了一些关于三斜杠指令的东西。/// <reference path="./global.d.ts"当我在 index.d.ts 文件的顶部手动放置一个三斜杠指令时,一切都神奇地开始工作了。然后我进一步研究了 tsconfig 如何替换了三斜杠指令。这是我一直在寻找的答案:

消费应用:

{
  "include": [
    "src/**/*",
    "node_modules/@xxxyyy/libraryname/types/global.d.ts"
  ],
  "exclude": [
    // I had to remove "node_modules" from this list
    "ci-output",
    "unitTest",
    "tutorials",
    "lib"
  ],
  "compilerOptions": {
    "module": "es2020",
    "target": "es2020",
    "sourceMap": true,
    "checkJs": true,
    "allowJs": true,
    "emitDeclarationOnly": true,
    "declaration": true,
    "outDir": "types",
    "downlevelIteration": true,
    "baseUrl": ".",
    "paths": {
      "*": [ "AppMain", "./src/component/app-main.js" ],
      "/xxxyyy/libraryname.min.js": [ "libraryname", "./node_modules/@xxxyyy/libraryname/types/index.d.ts" ]
    }
  }
}

推荐阅读