Borek Borek - 29 days ago 19
TypeScript Question

TypeScript module augmentation overwrites the original module?

In my Node.js / Express app, I've had Headers.ts file for quite a while with this content:

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;
}
}


It used to compile fine, however, after the recent
rm -rf node_modules
and
npm install
again, I'm getting a lot of errors like

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


It seems that the core issue is that
node_modules/@types/express/index.d.ts
resolves the
import * as core from "express-serve-static-core"
to my small augmentation and skips loading of the real thing entirely. I don't know why because I do have a folder
node_modules/@types/express-serve-static-core
properly installed.

What could it be?

Answer

Judging from the:

import * as http from 'http';

inside of your module declaration, you are not, in fact writing a module "agumentation" like you want, but rather replacing the existing module.

In order to write a module augmentation you would need to write it as this:

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;
    }
}

The first thing to note, is that it should me a external "file" module (it should have imports and exports).

The second thing to note is that the import * as http should go outside the module augmentation at is not legal inside.

The declared module now serves strictly as an augmentation. It will not over-write or replace the existing express-server-static-core module. In fact, that module is required to exist for it to be augmented (if you misspell the module name it would not compile' for example).

I cannot tell from your example why your code worked before. Perhaps there were differences in how express-server-static-core declaration files were implemented before. But if you follow this example, things should work for you.