在打字稿内部模块中使用外部打字稿库

Using an external typescript library within a typescript internal module

本文关键字:外部 模块 内部      更新时间:2023-09-26

假设您需要在内部模块中使用打字稿/节点库,该模块分布在多个.ts文件中。

ApiRepositoryHelper.ts

import * as requestPromise from "request-promise"; 
module ApiHelper {
   class ApiRepositoryHelper extends DataRepositoryHelper {}
}

DataRepositoryHelper.ts

module ApiHelper {
   class DataRepositoryHelper {}
}

一旦我添加该行: import * as requestPromise from "request-promise";DataRepositoryHelper变得无法进入。解决方案是什么?

观察:

如果我错了,请纠正我:

  1. 打字稿内部模块可以拆分为多个文件。
  2. 打字稿外部模块不能。
  3. 如果在内部模块(称为"A")的作用域之外添加对外部模块(例如 jQuery)的引用,则在同一文件中,可以在 A 中使用 JQuery。但是,您的内部模块"A"在项目的其余部分变得无法访问。
  4. 如果您有外部模块
  5. ,则可以引用其他外部模块。
  6. 您不能引用内部模块范围内的外部模块,您将获得"命名空间中的导入声明无法引用模块"。

我已经阅读了:在 Typescript 中从其他模块引用模块的正确方法。

我还读过:

如果内部模块前面有一个导入语句,则它不起作用,但我不同意:

您可以在没有内部模块的情况下很好地组织代码

仅仅因为,

module ApiHelper {
 class myClass {}
}

比,

import {Model} from "../../../lib/interfaces/model/Model";
import {List} from "../../../lib/classes/helper/List";
import {Serializable} from "../../interfaces/model/Serializable";
import {DataRepository} from "../../../lib/interfaces/data/DataRepository";
import {ModelFactory} from "../../interfaces/model/modelFactory";
import {DefaultApiParser} from "./DefaultApiParser";
import {ApiItemParser} from "./ApiParser";
//Insert two hundred other imports here...
export class MyClass{}

此外,在我看来,使用模块是优越的,因为您没有使用文件系统来引用您的类(这是推荐的方式?!) - 而只是将它们分开而不关心它们在哪里。

相信我们!(那些试图烧伤自己的人),modules/namespaces最好尽可能避免。

使用它们可能会让您解决许多无趣的问题,例如

  • 文件的编译时排序(如何使用打字稿生成正确的文件排序?
  • 循环引用(Typescript、CommonJS和Browserify的循环依赖问题)
  • 等。。。

"更整洁"也值得商榷

  • 如果这能让你感觉更好 Java 开发人员在 Typescript 存在之前几年就已经拥有了许多导入文件,我希望他们的预期寿命不会比 Javascript 开发人员短(也是其中之一)。更严重的是,一些像Webstorm(12 EAP)这样的IDE会自动为您处理导入,甚至可以在编辑器中折叠它们,这样它们就不会"污染"代码视图。

  • 此外,您正在做的事情在某种程度上是一种import *,从代码设计的角度来看,不导入您只需要的东西是有争议的。

总体而言,使用外部模块的隔离效果更好。

现在假设您的代码分为两部分:API 和实现,并且您希望在实现类中一次导入所有 API 定义,以避免多个导入语句。

可以在 API"部分"中创建一个重新导出所有内容的api.ts文件,即

export * from 'interfaces/model/Model' 
export * from 'interfaces/model/Interfaces'
export * from 'interfaces/model/Serializables'
...

然后在实现类中,只需在命名空间下导入单个api.ts文件,例如;

import * as api from '../api/api.ts'

然后可以访问所有API定义的导出,如api.Listapi.MyModel等...

但是既然你已经做到了,为什么不一路走下去,为你的API定义创建一个外部模块呢? :)

创建库

不幸的是,我目前找不到这方面的明确资源。

创建库的 TL;DR 为:

  • 创建一个index.ts,用于重新导出要在库中公开的所有定义
  • 使用 --declaration 标志编译库文件以自动生成键入
  • typings条目添加到指向生成的index.d.ts文件的package.json

要使用库:

  • 像任何其他库一样将其放在node_modules文件夹中
  • 简单import * as mylib from 'mylib':它将自动导入所有导出的定义类型

这里有一个简短的提法

你也可以看看我在那里写的LibraryUsage段落

如果我找到更好的资源,我会更新这个答案