The DefinitelyTyped definition of the Node built-in IncomingMessage (the type of req in the (req, res, next)
arguments) has defined url
to be nullable. Here's the snipped parts of the definition file:
// @types/node/index.d.ts
declare module "http" {
export interface IncomingMessage {
/**
* Only valid for request obtained from http.Server.
*/
url?: string;
}
}
As the comment says, this is because this property is only valid when you're getting an instance of this IncomingMessage from the http.Server. In other uses it won't exist, hence, it's nullable.
However, in my case, I know that I'm only getting these instances from http.Server, and so it's kinda annoying that I can't just access the property without extra guards.
import { IncomingMessage, ServerResponse } from 'http';
function someMiddleware(req: IncomingMessage, res: ServerResponse, next: Function) {
const myStr: string = req.url; // bzzzt.
// Argument of type 'string | undefined' is not
// assignable to parameter of type 'string'.
}
It's probably good to mention that I'm using TS 2.0.3 with strictNullChecks
, which is not enabled on the Typescript Playground.
Here's the question. Is it possible to override that definition across my application so that url
is not nullable?
Here's what I've already tried... adding this to one of my files:
declare module 'http' {
interface IncomingMessage {
url: string;
}
}
...however that is disallowed: "Subsequent variable declarations must have the same type". This is explained in the documentation.
The only thing I can think of thus far is to create my own module which imports, extends and then exports the interfaces:
// /src/http.ts
import { IncomingMessage as OriginalIM } from 'http';
export interface IncomingMessage extends OriginalIM {
url: string;
}
// src/myapp.ts
import { IncomingMessage } from './http'; // <-- local def
function someMiddleware(req: IncomingMessage) {
const str: string = req.url; // all good
}
So, this works, but it seems so wrong.