使用 TypeScript 声明 (*.d.ts) 和接口的正确方法?

Posted

技术标签:

【中文标题】使用 TypeScript 声明 (*.d.ts) 和接口的正确方法?【英文标题】:The correct way to use TypeScript declarations (*.d.ts) and interfaces? 【发布时间】:2017-11-14 15:32:38 【问题描述】:

在TypeScript中使用接口似乎有两种方式:我可以在普通的.ts文件中定义它们并导入它们,或者我可以在.d.ts文件中定义它们并让编译器从node_modules/中自动发现它们@types 或通过在 tsconfig.json 中添加 typeRoots 的相关路径,它们变得“神奇地”随处可用。

目前我有两个项目:一个客户端 (React) 和一个服务器 (Express),它们都是用 TypeScript 编写的。我在两个项目中都有某些接口,为了避免项目之间的依赖关系,我将公共接口提取到一个单独的项目到声明文件中。然后我以这种方式将项目添加为开发依赖项:

"@types/my-definitions": "git+ssh://git@github.com/myaccount/my-definitions.git"

这样TypeScript编译器会自动从node_modules/@types中找到接口,我就不用导入接口了。

我的问题是,这是一个好习惯,还是我应该在普通的 .ts 文件中使用接口,将项目作为普通依赖项导入并显式导入我正在使用的接口?每种方法的优缺点是什么?

【问题讨论】:

【参考方案1】:

.d.ts 文件是根据您的 .ts 文件生成的 typescript 项目(连同已编译的 JS)的输出。

通常这些是通过导入引入的,而不是被神奇地发现,因为它们位于一个特殊命名的文件夹中。

当您使用由 DOM/BOM/NodeJS 定义的环境 JS 全局变量时,您确实希望将 .d.ts 放在那个神奇的文件夹中以便所有代码都可以使用它们。您不需要显式导入它们,它们总是可用的(就像它们在 javascript 中一样)

但是,在处理实际库(输出 JavaScript 代码)时。您应该只通过 package.json 导入库并配置 TypeScript 以通过查看 node_modules 来解析模块。

示例

调用document.createElement() 返回htmlElement。通过添加环境定义,您不必导入 document 对象。

但是,假设您使用的是 Angular,当您想使用 Angular 类时,您必须显式导入它

import Component from "@angular/core"

TypeScript 会知道在 node_modules/@angular/core 中查找 ts 文件。它可能是原始的.ts,但通常不会打包为 TypeScript 项目的输出,通常你只会得到编译后的 JS 和 .d.ts 文件。

总结

您应该将您的可重用代码视为像 angular 一样的第三方库,并以同样的方式导入它。不要神奇地将这些定义添加到环境中(我们有足够多的全局变量)

【讨论】:

以上是关于使用 TypeScript 声明 (*.d.ts) 和接口的正确方法?的主要内容,如果未能解决你的问题,请参考以下文章

在全局声明 typescript .d.ts 中声明进程变量

TypeScript:类型标注和d.ts类型声明文件的使用

Typescript 生成带有 `#private;` 字段的声明 d.ts 文件

Typescript 未检测到声明“d.ts”文件中不存在的类型名称的错误

如何引用由 NPM 包中 tsc 的“声明”选项生成的 TypeScript .d.ts 文件中声明的类型?

TypeScript 类型定义文件(*.d.ts)自动生成工具