【问题标题】:Adding properties to existing TypeScript interface via module augmentation has no effect通过模块扩充向现有 TypeScript 接口添加属性无效
【发布时间】:2018-04-05 15:23:42
【问题描述】:

我有一个依赖于@types/hapi 的 Node 应用程序。我想向此模块中定义的类之一添加一个属性。我尝试通过模块扩充来定义我的新属性:

// my-custom-hapi-typings.d.ts
import * as hapi from 'hapi';

declare module hapi {
    interface Server {
        myProperty: string;
    }
}

这不会导致任何编译器错误,但也不会将myProperty 属性添加到Server 类。当我尝试像这样引用该属性时,我仍然在项目的其他地方遇到错误:

// my-other-file.ts
import * as hapi from 'hapi';

const server = new hapi.Server({ ... });

// error: Property 'myProperty' does not exist on type 'Server'.
server.myProperty = 'hello'; 

为什么 TypeScript 编译器似乎忽略了我的 .d.ts 文件?我是否需要“导入”文件或以某种方式让 TypeScript 编译器知道该文件存在?我的印象是,只需在源目录中放置一个 .d.ts 文件就足以让 TypeScript 接受这些增强。

【问题讨论】:

  • 顶级import 使文件成为模块。尝试删除它。
  • 感谢@Aaron 的回复,但我只是尝试删除顶级import,结果是一样的。
  • 尝试将“hapi”放在引号中:declare module "hapi"。您可能还需要exportServer 接口。
  • @Aaron - 将'hapi' 放在引号中解决了这个问题!谢谢!不知道我明白为什么。如果您想添加您的评论作为答案,我会接受。
  • 当然,我会尽量在回答中解释...

标签: typescript typescript-typings typescript2.0 typescript-definitions typescript-declarations


【解决方案1】:

这是你的问题:

declare module hapi {

这实际上是在定义一个namespace,使用早于 ES6 模块的旧语法,这些模块曾经被称为“内部模块”。编写module hapi 与编写namespace hapi 相同,这是当今的首选语法。 More on namespaces vs modules here.

对于declare an external module,您只需将模块名称放在引号中即可:

[...] 使用类似于环境命名空间的构造,但我们使用module 关键字和引用的模块名称,这些模块将可用于以后的导入。

换句话说,只需将hapi 放在引号中:

declare module "hapi"

现在你有一个环境my-custom-hapi-typings.d.ts不需要直接导入)外部模块定义(声明import "hapi"给你什么),你可以扩充里面声明的内容。

如果您将鼠标悬停在 module hapimodule "hapi" in the Playground 上,您会在工具提示中看到不同之处:

是的,由于其背后的历史,它是微妙而令人困惑的。

【讨论】:

  • 感谢@Aaron 的详尽解释。尽管我需要做的唯一更改是将'hapi' 括在引号中。如果我删除 import 语句,我的声明似乎是 覆盖 hapi 模块定义而不是 augmenting 它 - 我可以访问的唯一属性是我定义自己。所以我认为import 声明对于扩充是必要的。
  • @NathanFriend 嗯,你是对的。我认为它实际上是一个顶级的export,使它成为一个模块,或者作为一个模块实际上并没有改变declare module "hapi" 的效果。您也可以在模块声明中导入。我会编辑我的答案......不希望这个答案误导任何人。 :)
猜你喜欢
  • 2017-07-22
  • 1970-01-01
  • 2015-01-24
  • 1970-01-01
  • 2021-06-29
  • 2021-12-19
  • 2016-10-11
  • 1970-01-01
  • 2016-01-12
相关资源
最近更新 更多