【问题标题】:Typescript does not resolve definition file for npm packageTypescript 无法解析 npm 包的定义文件
【发布时间】:2018-06-07 15:12:48
【问题描述】:

我刚刚发布了一个用 typescript 编写的 npm package。目前,我很难获得打字稿(webback 和 vscode)识别的定义。到目前为止唯一有效的解决方案是创建一个文件夹,其定义在 node_modules/@types

简而言之,这是我的包设置:

tsconfig.json

{
    "compilerOptions": {
        ...
        "outDir": "./lib/",
        "declaration": true,
        "declarationDir": "./src/",
    }
}

package.json

{
    ...
    "types": "./index.d.ts",
}

index.d.ts

/// <reference path="src/nano-data-binding.d.ts" />

src/nano-data-binding.d.ts

我将它保存在 /src 中,因为它是自动生成的,我无法控制导入的路径。此外,如果我尝试仅使用 declare var ... 而不使用 import export 语句来获取脚本而不是模块。

import { StringOrHTMLElement } from './interfaces/nano-data-binding';
export declare function nanoBind(parent: HTMLElement, ...selectors: StringOrHTMLElement[]): HTMLElement[];
export declare function nanoBindAll(parent: HTMLElement, ...selectors: string[]): HTMLElement[];

请随意安装包,也许只是某个地方的一个小错误。基本上我想将nanoBind()nanoBindAll() 声明为全局变量。

编辑

我尝试过的其他东西。没有任何效果。

package.json - Npm 包

{
    ...
    "types": "lib/nano-data-binding.d.ts",
    "typings": "lib/nano-data-binding.d.ts",
    "typescript": {
        "definition": "lib/nano-data-binding.d.ts"
    },
}

tsconfig.json - 本地项目

{
    ...
    "files": [
        "node_modules/nano-data-binding/lib/nano-data-binding.d.ts"
    ]
}

【问题讨论】:

  • 你的包中的打字文件分发了吗?您也不需要重定向(使用 index.d.ts 并使用 ///
  • 顺便说一句,/// &lt;reference 用于全局脚本文件,作为一个包,您不会使用该语法。只需import '...'
  • 我在发布之前已经尝试了所有这些建议,我指向的是实际文件。我也尝试使用typings。以及其他各种事情。它只是拒绝注册为定义。定义肯定在包里。
  • 我一直在查看其他软件包,试图弄清楚我是否做错了什么。没有什么突出的。除了等待错误之外,有没有其他方法可以确认接口已加载?
  • 你能展示一下 nano-data-binding.d.ts 的样子吗?它应该是自动的,除了 package.json 中的types/typings: ... 之外,您无需执行任何操作。例如,请参阅我的任何包裹。例如color-map

标签: typescript npm


【解决方案1】:

在您的package.json 中,您需要将types 字段重命名为typings 是的,这里不需要三斜杠指令

【讨论】:

  • 我使用了三斜杠以便能够添加更多定义,实际上它并不是真正需要的。在发布之前,我尝试直接指向文件夹和实际定义所在的根 index.d.ts
  • “types”和“typings”是同义词typescriptlang.org/docs/handbook/declaration-files/…
【解决方案2】:

终于找到了有用的东西。看起来在根级别使用index.d.ts 或者在包的package.json 中指定自定义路由就足够了。

问题出在我的定义上。它需要声明一个模块。

index.d.ts

type StringOrHTMLElement = string | HTMLElement
declare var nanoBind: (parent: HTMLElement, ...selectors: StringOrHTMLElement[]) => HTMLElement[];
declare var nanoBindAll: (parent: HTMLElement, ...selectors: string[]) => HTMLElement[];

declare module 'nano-data-binding' {
    export var nanoBind: (parent: HTMLElement, ...selectors: any[]) => HTMLElement[];
    export var nanoBindAll: (parent: HTMLElement, ...selectors: string[]) => HTMLElement[];
}

比它的导入方式

ma​​in.ts

import * as ndb from 'nano-data-binding' // Imports script and definition
require('nano-data-binding') // Ignores definition

【讨论】:

  • 这不是办法。所以我知道你的问题是什么。将发布答案
  • 这是一种增强别人类型定义的方法。我在上面发布了一个答案。类型-> package.json 中的类型
  • 我在打字稿文档中找到了globals.d.ts。也许我弄错了。说namespace 是针对全局变量的,这是我的情况。
【解决方案3】:

您遇到的问题是由于您的 tsconfig.json 尝试显式包含输入文件。 当您在 package.json 中指定 typestypings 字段时,npm 包类型文件会自动加载。

当您在 tsconfig.json 中删除 files 数组中的条目时,它应该可以正常工作。

您找到的解决方案(添加declare module 'nano-data-binding' { })是为某些无需分型的包创建自定义分型的解决方案。

从技术角度来说,当一个类型文件 (d.ts) 不包含顶级 import export 语句时,它是一个环境脚本文件,它是全局范围的。这就是为什么您需要declare module '...' 来指明您要为哪个模块添加类型。

你通常像How to consume the Moment.js TypeScript definition file if my site is already using moment.min.js?那样使用它们

【讨论】:

  • 问题是我前段时间从tsconfig.json 中删除了files 选项。我做的很多测试都是在没有这个选项的情况下运行的。我会继续研究它。我希望我能找到真正的麻烦制造者。也许我应该尝试将它导入一个干净的项目中。也许有什么干扰。我会做一些测试并报告结果。谢谢你的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-05
  • 2019-11-05
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
相关资源
最近更新 更多