【问题标题】:TypeScript module augmentation overwrites the original module?TypeScript 模块扩充会覆盖原始模块?
【发布时间】:2016-11-07 12:06:24
【问题描述】:

在我的 Node.js / Express 应用程序中,我已经拥有 Headers.ts 文件很长一段时间了,其中包含以下内容:

type HttpHeader = 'X-My-Header' | 'X-My-Other-Header' | 'X-Another';

declare module 'express-serve-static-core' {
    import * as http from 'http';
    interface Request extends http.IncomingMessage, Express.Request {
        header(name: HttpHeader): string | undefined;
    }
}

它曾经编译得很好,但是,在最近的rm -rf node_modulesnpm install 再次之后,我遇到了很多类似的错误

error TS2339: Property 'get' does not exist on type 'Request'.
error TS2339: Property 'end' does not exist on type 'Response'.

似乎核心问题是node_modules/@types/express/index.d.tsimport * as core from "express-serve-static-core" 解析为我的小增强并完全跳过加载真实的东西。我不知道为什么,因为我确实正确安装了一个文件夹 node_modules/@types/express-serve-static-core

会是什么?

【问题讨论】:

  • 您使用的是什么打字稿版本?您使用的语法似乎不合法(您通常不能在模块扩充中进行导入)。你在任何地方导入express-serve-static-core 吗?
  • 一些关于如何导入/使用 Request 类型的示例也会有所帮助。

标签: typescript


【解决方案1】:

从以下方面来看:

import * as http from 'http';

在你的模块声明中,你实际上并不是在写一个你想要的模块“agumentation”,而是替换现有的模块。

为了编写模块扩充,您需要这样编写:

import { Request} from 'express-serve-static-core';
import * as http from 'http';

export type HttpHeader = 'X-My-Header' | 'X-My-Other-Header' | 'X-Another';

declare module 'express-serve-static-core'{
    export interface Request extends http.IncomingMessage, Express.Request {
        header(name: HttpHeader): string | undefined;
    }
}

首先要注意的是,它应该是一个外部“文件”模块(它应该有导入和导出)。

要注意的第二件事是import * as http 应该放在模块扩充之外,在里面是不合法的。

声明的模块现在严格用作扩充。它不会覆盖或替换现有的express-server-static-core 模块。事实上,该模块需要存在才能对其进行扩充(例如,如果您拼错了模块名称,它将无法编译)。

我无法从您的示例中看出为什么您的代码以前有效。之前express-server-static-core 声明文件的实现方式可能有所不同。但是,如果您遵循此示例,则应该对您有用。

【讨论】:

  • 您确定import * as http 吗? TypeScript 编译器甚至有一个明确的消息,我应该尝试将导入移动到外部范围(在某些情况下),所以它有点假设它是有效的内部。这个环境声明之前编译得很好,也可以很好地处理模块解析。
  • 是的,我很肯定。你是对的,在一个普通的全局环境声明中它会起作用,但你的问题是你应该使用全局环境声明。您正在尝试做的是 augment 现有模块中的类型。 import 声明不允许在模块 augmentation 中使用,您将获得 TS2667: Imports are not permitted in module augmentations
  • 我什至不确定我是否正确地进行了请求增强,请参见例如github.com/DefinitelyTyped/DefinitelyTyped/blob/…。但这对我也不起作用,我想我会创建一个单独的问题。
  • 哦,它在我的项目中的 plan .ts 文件中工作。以前,我(出于某种原因)尝试将其添加到 customtypes/express-serve-static-core/index.d.ts(我已将 customtypes 注册为 tsconfig.json 中的类型根),它可能会干扰 TypeScript 的模块解析。但是,我正在使用这种方法来扩充其他一些模块,例如 async,它似乎工作正常。这可能是让我感到困惑的地方。
  • 您建议将这个模块扩充存储在哪里?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-21
  • 1970-01-01
  • 1970-01-01
  • 2021-02-06
  • 1970-01-01
相关资源
最近更新 更多