TypeScript 接口是不是应该在 *.d.ts 文件中定义
Posted
技术标签:
【中文标题】TypeScript 接口是不是应该在 *.d.ts 文件中定义【英文标题】:Should TypeScript Interfaces Be Defined in *.d.ts FilesTypeScript 接口是否应该在 *.d.ts 文件中定义 【发布时间】:2016-10-18 16:20:15 【问题描述】:TypeScript 新手问题。在我们的项目中,我们使用了一些外部 javascript 库,我们需要在其中添加 *.d.ts 文件。我了解这个用例以及我们需要这样做的原因。
但是,对于我们自己定义的接口,我的一位开发人员建议我们在 *.d.ts 文件中定义它们,这样我们就可以访问接口类型,而无需将其导入需要使用的模块中它。
例如,我们想为“错误优先回调”函数创建一个接口,以便我们可以在许多领域重用它。
所以不是这个...
export function helloWorldEventually(callback: (err: Error, result: any) => void)
callback(null, 'Hello World');
我们可以像这样为错误优先回调定义一个接口...
export interface ErrorFirstCallback
(err: Error, result: any): void;
然后像这样使用它......
export function helloWorldEventually(callback: ErrorFirstCallback)
callback(null, 'Hello World');
一开始我只是在ErrorFirstCallback.ts中定义了ErrorFirstCallback接口,为了引用而导入。
另一位开发人员建议我们将其放入 *.d.ts 文件中,然后我们无需导入它即可引用它。
我们定义的接口何时应该在 *.d.ts 文件和 *.ts 文件中定义。
谢谢!
【问题讨论】:
afaik。*.d.ts
-files 主要用于用类型注释普通的 *.js
文件/库。我不确定我是否同意使用这样的定义文件,或者我是否将其放在 interfaces.ts
中,然后在主 ts 文件中引用。或者保持详细/安全并在每个需要它的文件中引用接口文件。
【参考方案1】:
声明文件描述了外部 JavaScript 库的形状。例如使用带有$
的jQuery 将导致没有声明文件的TypeScript 错误,因为$
或JQuery
未定义。因此,声明文件创建了一个接口,因此编译器知道“如果此变量是 JQuery 类型,则它必须具有函数 x,y,z”
为您的项目创建接口时,您应该将它们放在您喜欢的位置:在一个大的接口文件中,在每个接口的单独文件中,或者在它可能属于的文件中,但在声明文件中很不方便。
我个人喜欢为每个模块/类/接口设置单独的文件。但这只是口味问题。
考虑创建声明文件的唯一目的是让其他开发人员可以在他们的项目中使用您的最终 JavaScript 文件(不是 TypeScript!)。
【讨论】:
我将遵循这个一般规则:如果我正在创建一个接口,那么它应该只是一个普通的 *.ts 文件,但是如果我们需要添加一个接口或为外部 JS 键入模块,那么使用声明文件是有意义的。感谢您的回答! 您使用接口的次数越多,您就会越了解这一点。顺便提一句。您可以找到大多数库的定义文件on GitHub。【参考方案2】:你在使用typings
吗?这似乎是管理第三方类型的社区方式。这样您就不必管理定义其他开发人员的 API。
作为参考,Node 环境 d.ts 似乎只是在整个 API 中定义了 (err, res)
回调 (https://github.com/typed-typings/env-node/blob/master/6/node.d.ts)
【讨论】:
【参考方案3】:另一位开发人员建议我们将 [接口] 放在 *.d.ts 文件中,然后我们不需要导入它来引用它。
使用.d.ts
与.ts
文件与在本地/模块或全局/脚本范围内提供类型声明无关。
你可以export
接口ErrorFirstCallback
,所以其他人将不得不import
它。或者您不使用export
/import
使文件成为全局脚本。然后,ErrorFirstCallback
可以在没有导入的情况下使用。在这种情况下,如果文件具有 .ts
或 .d.ts
扩展名,则无关紧要。
我们定义的接口何时应该在 *.d.ts 文件和 *.ts 文件中定义。
重要的是,.d.ts
文件 are only seen as compiler input 而不是发送到您的 dist
/build
文件夹。
作为一个好的经验法则,如果您想将类型作为 npm 包或公共类型化 API 的一部分提供,那么您可以将类型放入 .ts
中,以便通过构建步骤让您的生活更轻松(它将发出作为编译器输出)。
您可以将.d.ts
文件用于项目内部使用的类型。
【讨论】:
谢谢,这澄清了很多事情。 - 即使您将文件命名为 *.d.ts 或 *.ts,唯一重要的是您是否有***导出。如果您有一个导出,它将是一个需要导入的模块。如果您没有导出,它将被视为全局脚本,可用于所有模块。也就是说,是否有理由使用一种命名约定与其他命名约定 - *.d.ts vs *.ts ? 是的,完全正确。关于d.ts
与.ts
:.d.ts
主要是编译器用于输出类型声明的扩展,由--declaration
或--emitDeclarationOnly
触发。对于自己的类型,始终使用 .ts
扩展名是安全的。 .d.ts
的情况可能很少见 - 例如您开发了一个库并希望确保某些类型保留在内部而不是发出,例如全局(类型)声明或模块扩充。以上是关于TypeScript 接口是不是应该在 *.d.ts 文件中定义的主要内容,如果未能解决你的问题,请参考以下文章
Facebook JavaScript SDK 是不是有 TypeScript 接口定义