如何设计用于导出的打字稿项目
Posted
技术标签:
【中文标题】如何设计用于导出的打字稿项目【英文标题】:How to design a typescript project for export 【发布时间】:2018-06-21 11:13:45 【问题描述】:我很抱歉,因为我是 js 生态系统的新手。我在一个使用打字稿的地方工作,这很棒,因为它帮助我摆脱了静态语言的背景。但是我仍然不了解包装/模块系统,尤其是与打字稿定义结合使用。
我正在编写一个模块,其中包含一组描述 Web 服务 API 合同的接口,供客户端库和 API 服务本身使用。如果这是 C#/Java 或其他东西,我会编写我的接口文件,将其打包、发布,然后通过说来使用它
import GetWizardsResponse from StuffInc.Contract.Wizards
这就是我使用打字稿库的方式,所以我写了
export interface GetWizardsResponse
wizards: Wizard
currentPage: number
count: number
然后在我的ts.config
中我有"declaration": true
所以在tsc
之后我得到Wizards.d.ts
和Wizards.js
。当我 npm publish
这个时,我必须通过执行以下操作来消耗它:
import GetWizardsResponse from '@StuffInc/contracts/Wizards'
但是当我环顾四周时,更常见的是看到这样的导入:
import * as Express from 'express'
或
import Response, NextFunction from 'express'
所以我使用我的包应该是这样的:
import GetWizardsResponse from '@StuffInc/contracts
这样我可以拥有/wizards
、/goblins
、/elves
,但导入始终来自“来自@StuffInc/contracts”。这就是我所做的(这就是我应该做的对吗?所有的 NPM 包都是这样的)
为此,我认为我需要将所有内容放在一个 index.d.ts
文件中。我是否仍然可以在逻辑单独的文件中编写我的代码,但将其构建到一个定义中,以便其他开发人员的猜测工作更少?
【问题讨论】:
我在使用export default xxx
时没有得到任何提示,但export xxx
工作正常。不知道为什么,估计是bug,反正TS里别用export default
我不太确定您遇到了什么问题,但我不禁注意到您在 .ts
示例中的任何地方都没有使用任何 ;
或 ,
我肯定会导致大量错误。例如,界面应该看起来像export interface GetWizardsResponse wizards: Wizard, currentPage: number, count: number
,在每个界面之间使用逗号。然后是你的导入,它应该看起来像import GetWizardsResponse from '@StuffInc/contracts/Wizards';
,最后使用;
。如果您可以更具体地了解您正在做什么并显示Wizards
的代码,我可能会提供帮助。
@Optiq 对不起,是的,你是对的。我只是徒手写了代码。我的真实代码更无聊,所以我特意使用了一些奇特的例子来确保重点放在问题上。虽然 out 项目不使用 ;
并且如果您使用它们,linter 会抱怨。显然它们是可选的。这是我对这种语言感到困惑的众多原因之一,有多种做事方式非常有趣
【参考方案1】:
你已经很接近了,唯一想要获得漂亮名字的东西就是带有export * from '@StuffInc/contracts/Wizards'
的index.ts
诀窍是您可以从不同的文件中多次导出某些内容。 像 webpack 这样的模块加载器会知道寻找以您的项目命名的 index.d.ts 或 .d.ts(moment has a moment.d.ts)。
现在 js/ts 中的模块有点复杂,但是随着 es6 模块变得越来越正常,它变得越来越好。还有一些叫做默认导出的东西,它们允许import package from 'package'
语法。像 Moment 这样具有全局命名空间的工具应该使用它,它也允许命名导入。 import moment, Duration from 'moment'
。不过,没有多少模块使用默认值,所以你不能像那行一样从那一刻开始导入。你必须这样做import * as moment from 'moment'
。如果它们具有声明的命名空间而不是显式的导出/默认值,您将看到这一点。我的观点是,如果可以的话,你想远离 * 导入,你将不得不使用它们来导入一个没有设置它们的节点模块,但是通过显式导入模块捆绑器可以使你的包变得更小,使用诸如摇树之类的技术和代码拆分。
这是对我迄今为止能够弄清楚的内容的快速复习,但我会对模块进行更多研究。
【讨论】:
感谢您提供详细的概述。所以我的目标应该是在我的模块的根目录中有import Wizard from 'myModule' be possible to module clients can be more efficient? Makes sense. To do that I need an
index.d.ts`,它以某种方式指向\wizards
或其他任何文件?
是的。有一些工具可以生成定义文件,所以如果你使用 webpack,大多数 ts 加载器都有输出定义文件的选项。 tsc 还有一个 --declaration
标志,它将生成 .d.ts 文件。以上是关于如何设计用于导出的打字稿项目的主要内容,如果未能解决你的问题,请参考以下文章