node.js - I TypeScript, hvordan implementerer jeg et grensesnitt med (a: type, b: type): any?


Spesifikt prøver jeg å sette opp server-side TypeScript-kompilering for Express.

En av grensesnittene som eksponeres er RequestHandler, med følgende struktur:

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

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

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

Jeg skrev følgende klasse:

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

Men dette gir feilen:

feil TS2345: Argument av typen 'typeof PageNotFound' kan ikke tildeles til parameter av typen 'RequestHandler'. Typen 'typeof PageNotFound' gir ingen samsvar med signaturen '(req: Request, res: Response, next: NextFunction): any'

Noen forslag der ute? Jeg er ikke sikker på hva jeg gjør galt.

Svar #1

RequestHandler er et grensesnitt som spesifiserer noe med en kalle-signatur, som klasser ikke kan implementere. Du vil ha en vanlig funksjon:

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

Hvis grensesnittet hadde new foran metodesignaturen, ville det definert formen på konstruktøren til klassen din, men det er ikke tilfelle.

En annen måte å tenke på det på er dette: når du bruker en klasse, definerer du en funksjon som må kalles med new. Kommer Express til å kalle "new PageNotFound(...)" eller kaller det "pageNotFound(...)"?

Som Ryan Cavanaugh, en av utviklerne av TypeScript, sa det her:

Mer formelt, en klasse som implementerer et grensesnitt er en kontrakt på hva en instans av klassen har... - Ryan Cavanaugh 15. nov. '12 kl. 23:57

Svar #2

Du vil holde det enkelt, klasser er for objekter som brukes mer enn én gang. Modulen express gir deg Router-objektet med de riktige egenskapene.

import * as express from 'express';
const router = express.Router();

router.get('/', (req: express.Request, res: express.Response, next: express.NextFunction) => {
    res.render('index', {
        title: 'Express'
    })
});

export = router; 

Relaterte artikler