borisyankov/DefinitelyTyped — pull request #1994 by yortus (2014-04-06 05:54:27+00:00)
Title: Open express.d.ts interfaces

### PR Description

This PR adds the following interfaces to express.d.ts that are open to declaration merging:
* `Express.Request`
* `Express.Response`
* `Express.Application`

The existing declarations in express.d.ts now extend the above new interfaces, but are otherwise completely unchanged. No other type declaration files need to be altered.

This PR also amends passport.d.ts, which can now simply merge its extended members into the open interfaces. This change can be removed from the PR if preferred.

### Rationale

Express's Request, Response, and Application types are open to modification by design. There are many libraries that do this (examples: [passport](http://passportjs.org/guide/login/), [express-expose](https://github.com/visionmedia/express-expose), [connect-flash](https://github.com/jaredhanson/connect-flash), [express-annotations](https://github.com/yahoo/express-annotations) [express-yui](https://github.com/yahoo/express-yui), [request-extend](https://github.com/jsantell/node-request-extend)), as well as in-house applications. It's also discussed e.g. on StackOverflow (examples: [1](http://stackoverflow.com/questions/11337402/is-it-ok-to-add-data-to-the-response-object-in-a-middleware-module-in-express-js) [2](http://stackoverflow.com/questions/15111665/is-it-possible-to-extend-express-application) [3](http://stackoverflow.com/questions/15057857/node-js-express3-middleware-to-add-render-data-to-all-render-requests) [4](http://stackoverflow.com/questions/18304436/in-express-and-node-js-is-it-possible-to-extend-or-override-methods-of-the-resp) [5](https://groups.google.com/forum/#!topic/express-js/Mk4Rc_SlJ4c)).

Note that TypeScript's [guide to writing type declaration files](https://typescript.codeplex.com/wikipage?title=Writing%20Definition%20%28.d.ts%29%20Files) states:

> Whether or not you want your declarations to be extensible in this way is a bit of a judgement call. As always, try to represent the intent of the library here.

In its current form, express.d.ts does not reflect the library's intent in this regard, as it declares Request, Response and Application in a manner that makes them closed to extension. This is a pain when using libraries like the above, as well as for in-house code. One must either **(a)** do without static type checking and intellisense for the extended members, or **(b)** maintain a separate express.d.ts with the appropriate modifications directly patched in, or **(c)** coerce TypeScript's type deductions to use specially defined types (as seen in passport-test.ts).

### Further Considerations

My previous attempt at solving this problem in #1959 was more far-reaching and also changed node.d.ts. It caused a lot of debate. This change is very simple, and importantly is confined to express.d.ts.

An objection to this PR is that it adds the name `Express` to the global declaration space. In response to this objection it might be noted:
- There is no other way to declare a type that remains open to merging.
- It only adds one global name, and this being one of the most popular libraries out there, it is unlikely that another library will try to adopt the same name and cause a clash.
- DT is strewn with global names, even for libraries that don't intend their types to be open. If ever there was a case for adding a single global name, it is surely for a extensively used library, whose types are intended to be open.

Another objection is that the merged members are visible project-wide. I don't know about every project, but in my experience, this is the expected pattern anyway. A typical project configures express and its middleware once, and uses that middleware throughout the application. Different projects may use different middleware, but as long as each project includes only the typings it uses, the type system will reflect the actual middleware used project-wide, but not across projects, which I believe is the common case.