Alexander Alexander - 3 months ago 18
Node.js Question

In TypeScript, how do I implement an interface with (a: type, b:type): any?

Specifically, I'm trying to setup server sided typescript compilation for express.

One of the interfaces exposed is RequestHandler, with the following structure:

// express-serve-static-core/index.d.ts

declare module "express-serve-static-core" {
...

interface RequestHandler {
(req: Request, res: Response, next: NextFunction): any;
}
}


I wrote the following class:

import * as express from "express";

class PageNotFound implements express.RequestHandler {

constructor (req: express.Request, res: express.Response, next: express.NextFunction) {
let viewFilePath: string = "404";
let statusCode: number = 404;
let result: Object = {
status: statusCode,
};

res.status(statusCode);
res.render(viewFilePath, {}, function (err: Error, html: string): void {
if (err) {
res.status(statusCode).json(result);
}
res.send(html);
});
}
}


However, this throws the error:

error TS2345: Argument of type 'typeof PageNotFound' is not assignable to parameter of type 'RequestHandler'.
Type 'typeof PageNotFound' provides no match for the signature '(req: Request, res: Response, next: NextFunction): any'


Any suggestions out there? I'm not sure what I'm doing wrong.

Answer

RequestHandler is an interface that is specifying something with a call signature, which classes cannot implement. You want a regular function:

function pageNotFound(req: express.Request, res: express.Response, next: express.NextFunction) {
    ...
}

If the interface had new in front of the method signature, it would be defining the shape of the constructor of your class, but that isn't the case.

Another way to think about it is this: when you use a class, you're defining a function that must be called with new. Is Express going to call "new PageNotFound(...)" or is it calling "pageNotFound(...)"?

As Ryan Cavanaugh, one of the TypeScript developers, put it here:

More formally, a class implementing an interface is a contract on what an instance of the class has... – Ryan Cavanaugh Nov 15 '12 at 23:57