通过模块扩充向现有 TypeScript 接口添加属性无效
Adding properties to existing TypeScript interface via module augmentation has no effect
我有一个依赖于 @types/hapi
的 Node 应用程序。我想将 属性 添加到此模块中定义的 classes 之一。我尝试通过模块扩充定义我的新 属性:
// my-custom-hapi-typings.d.ts
import * as hapi from 'hapi';
declare module hapi {
interface Server {
myProperty: string;
}
}
这不会导致任何编译器错误,但它也不会将 myProperty
属性 添加到 Server
class。当我尝试像这样引用 属性 时,我的项目中的其他地方仍然出现错误:
// 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
文件?我是否需要 "import" 文件或以某种方式让 TypeScript 编译器知道该文件存在?我的印象是,只要在源目录中放置一个 .d.ts
文件就足以让 TypeScript 接受这些增强。
这是你的问题:
declare module hapi {
这实际上是在定义一个namespace
, using older syntax that pre-dates ES6 modules which used to be called "internal modules". Writing module hapi
is the same as writing namespace hapi
, which is the preferred syntax today. More on namespaces vs modules here.
到declare an external module你只需要将模块名称放在引号中:
[...] use a construct similar to ambient namespaces, but we use the module
keyword and the quoted name of the module which will be available to a later import.
换句话说,只需将 hapi
放在引号中:
declare module "hapi"
现在你有一个环境(my-custom-hapi-typings.d.ts
不需要直接导入)外部模块定义(声明import "hapi"
给你什么),你可以扩充其中声明的内容。
如果将鼠标悬停在 module hapi
和 module "hapi"
in the Playground 上,您会在工具提示中看到不同之处:
是的,由于其背后的历史,它很微妙且令人困惑。
我有一个依赖于 @types/hapi
的 Node 应用程序。我想将 属性 添加到此模块中定义的 classes 之一。我尝试通过模块扩充定义我的新 属性:
// my-custom-hapi-typings.d.ts
import * as hapi from 'hapi';
declare module hapi {
interface Server {
myProperty: string;
}
}
这不会导致任何编译器错误,但它也不会将 myProperty
属性 添加到 Server
class。当我尝试像这样引用 属性 时,我的项目中的其他地方仍然出现错误:
// 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
文件?我是否需要 "import" 文件或以某种方式让 TypeScript 编译器知道该文件存在?我的印象是,只要在源目录中放置一个 .d.ts
文件就足以让 TypeScript 接受这些增强。
这是你的问题:
declare module hapi {
这实际上是在定义一个namespace
, using older syntax that pre-dates ES6 modules which used to be called "internal modules". Writing module hapi
is the same as writing namespace hapi
, which is the preferred syntax today. More on namespaces vs modules here.
到declare an external module你只需要将模块名称放在引号中:
[...] use a construct similar to ambient namespaces, but we use the
module
keyword and the quoted name of the module which will be available to a later import.
换句话说,只需将 hapi
放在引号中:
declare module "hapi"
现在你有一个环境(my-custom-hapi-typings.d.ts
不需要直接导入)外部模块定义(声明import "hapi"
给你什么),你可以扩充其中声明的内容。
如果将鼠标悬停在 module hapi
和 module "hapi"
in the Playground 上,您会在工具提示中看到不同之处:
是的,由于其背后的历史,它很微妙且令人困惑。