Typescript 在本地声明第三方模块

Posted

技术标签:

【中文标题】Typescript 在本地声明第三方模块【英文标题】:Typescript declare third party module locally 【发布时间】:2017-07-17 12:32:01 【问题描述】:

我正在构建一个打字稿项目并使用非打字稿库调用'draggabilly';

所以我尝试自己声明。

这是文件结构:

├── @types
│   └── draggabilly
│       └──index.d.ts
├── node_modules
├── package.json
├── README.md
├── src
│   ├── index.ts
│   └── application.ts
└── tsconfig.json

src/application.ts

import * as Draggabilly from 'draggabilly';

new Draggabilly('#dragItem', 
  // options...
);

......

这表明

找不到模块“draggabilly”的声明文件。 '/node_modules/draggabilly/draggabilly.js' 隐式具有“任何”类型。

所以我尝试创建本地声明文件:@types/draggabilly/index.d.ts:

export as namespace draggabilly;

export = Draggabilly;

declare class Draggabilly 
  constructor(selector: string, options: any);

然后在 tsconfig.json 中包含类型路径:


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

但错误仍然存​​在。所以我想知道这里出了什么问题以及在本地构建第三方模块声明文件的正确方法是什么

我在 github 上为这个问题创建了一个演示库: https://github.com/ZheFeng/test-ts-types

问题不仅在于我们如何在 .d.ts 文件中定义,还在于 typescript 根本找不到声明文件。

【问题讨论】:

签出这个可拖动的打字github.com/giespaepen/draggabilly/blob/… 谢谢艾文,我做到了。但是打字稿似乎无法识别我的声明文件。这就是为什么我把我的文件结构和配置放在上面。 【参考方案1】:

问题出在export = Draggabilly; 行——你必须使用特定于TypeScript 的语法import let = require("module") 来导入它:

来自TypeScript documentation:

使用 export = 导入模块时,必须使用特定于 TypeScript 的 import let = require("module") 来导入模块。

所以你的导入应该是:

import Draggabilly = require("draggabilly");


如果你想使用 ES6 风格的导入,你可以修改你的index.d.ts,如下所示:
export as namespace draggabilly;

export class Draggabilly 
  constructor(selector: string, options: any);

...并像这样导入它:

import * as draggabilly from 'draggabilly';

new draggabilly.Draggabilly('#dragItem', 
  // options...
);

【讨论】:

是的,你是对的。但问题是即使我更改为导出类 Draggabilly,错误仍然存​​在“找不到模块 'draggabilly' 的声明文件。'/node_modules/draggabilly/draggabilly.js' 隐式具有'任何'类型”。打字稿似乎忽略了我的本地声明文件 您能否使用您拥有的确切代码更新您的帖子。我似乎无法重现该错误。 感谢您的帮助萨拉瓦娜。我在 github 上为这个问题创建了一个演示库:github.com/ZheFeng/test-ts-types【参考方案2】:

为非基于 TypeScript 的 3rd 方模块提供声明文件时,declare module 必须在全局范围内,并且没有 import声明模块之外导出

@types/draggabilly/index.d.ts

declare module "draggabilly" 
    // import other libraries, optional
    // ...

    class Draggabilly 
        constructor(selector: string, options: any);
    

    export = Draggabilly;

src/application.ts

import Draggabilly = require("draggabilly");

new Draggabilly("#dragItem", 
    // options...
);

【讨论】:

以上是关于Typescript 在本地声明第三方模块的主要内容,如果未能解决你的问题,请参考以下文章

解决 TypeScript 引入第三方包,报无法找到模块“XXX”的声明文件错误

解决 TypeScript 引入第三方包,报无法找到模块“XXX”的声明文件错误

TypeScript(20): 声明文件

在为第三方库进行模块扩充时,如何在 VSCode 中为 JavaScript 中的代码库启用 TypeScript 智能感知?

TypeScript学习笔记 - 声明文件

LayaBox---TypeScript---模块