【问题标题】:How do I use a class defined in a TypeScript declaration file?如何使用 TypeScript 声明文件中定义的类?
【发布时间】:2018-05-04 10:44:53
【问题描述】:

我正在尝试为 this simple queue implementation 创建类型文件。

在我的 TS 项目中,我创建了一个名为 customTypings 的文件夹,并在我的 tsconfig.json 文件的 typeRoots 属性中指向它。

这是我的 .d.ts 文件的样子:

declare module 'queue-fifo' {
    export default class Queue {
        constructor();
        isEmpty(): boolean;
        size(): number;
        clear(): void;
        enqueue(data: any): void;
        dequeue(): any;
        peek(): any;
    }
}

我导入为:import Queue from 'queue-fifo';

然后我尝试创建Queue 类的实例:const queue = new Queue();

此时,我在 VS Code 中没有收到任何类型错误,也没有收到任何编译错误。但是,当我尝试通过调试器运行我的代码时,我得到:

Exception has occurred: TypeError
TypeError: queue_fifo_1.default is not a constructor
    at BinarySearchTree.bfs (/../binarySearchTree.ts:110:23)
    at testBst (/../binarySearchTree.ts:139:10)
    at Object.<anonymous> (/../binarySearchTree.ts:144:1)
    at Module._compile (module.js:632:14)
    at Object.Module._extensions..js (module.js:646:10)
    at Module.load (module.js:554:32)
    at tryModuleLoad (module.js:497:12)
    at Function.Module._load (module.js:489:3)
    at Function.Module.runMain (module.js:676:10)
    at startup (bootstrap_node.js:187:16)

如果我在该行中断,我会看到 Queue(我导入的)未定义,但 queue_fifo_1 已已定义,我可以使用该名称创建类的实例在调试控制台中。

有人可以解释我在声明/使用导致这种不良行为的声明中做错了什么吗?

【问题讨论】:

  • 尝试在你的主ts文件中使用export class Queue

标签: typescript typescript-typings


【解决方案1】:

解决方案

queue-fifo 模块使用 CommonJS 风格的 export = Queue,它与 ES6 导入不兼容,并且没有默认导出。 correct type definition 需要使用相同的 export = 样式语法:

declare module "queue-fifo" {
    class Queue {
        isEmpty(): boolean;
        size(): number;
        // etc
    }
    export = Queue;
}

可以使用 CommonJS 风格的导入来导入:

import Queue = require("queue-fifo");
const queue = new Queue();

ES6 导入

如果您想知道是否可以使用 ES6 语法导入此模块,您可以可能使用命名空间定义技巧:

class Queue { /* ... */ }
namespace Queue { /* empty */ }
export = Queue;

然后使用 ES6 通配符导入:

import * as Queue from "queue-fifo";
const queue = new Queue();

但这只能在非 ES6 环境中工作,例如像 Webpack 和 Rollup 这样的打包工具今天可以做到这一点,但未来的 ES6 兼容模块系统将无法做到这一点。在此处查看更多信息:What does "... resolves to a non-module entity and cannot be imported using this construct" mean?

【讨论】:

  • 绝妙的答案,但只有一点; “导出为命名空间”可能很容易与用于在 .d.ts 文件中定义 UMD 模块的export as namespace some_identifier 语法混淆
  • 完美。非常感谢您的解决方案和解释。我试图在我的项目中快速使用这个实现,因为当我练习自己的实现时,为了简单起见,我使用number 实现了它。在等待答案时,我了解了 TypeScript 泛型并将我的实现转换为使用它。双赢! :)
猜你喜欢
  • 2017-07-21
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 2019-03-08
  • 2017-07-30
  • 2021-10-13
  • 1970-01-01
相关资源
最近更新 更多