Tìm kiếm trang web

node.js - Trong TypeScript, làm thế nào để tôi triển khai một interface với (a: type, b: type): any?


Cụ thể, tôi đang cố gắng thiết lập biên dịch TypeScript phía server cho Express.

Một trong các giao diện được phơi bày là RequestHandler, với cấu trúc như sau:

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

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

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

Tôi đã viết lớp sau:

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

Tuy nhiên, điều này gây ra lỗi:

lỗi TS2345: Đối số kiểu 'typeof PageNotFound' không thể gán cho tham số kiểu 'RequestHandler'. Kiểu 'typeof PageNotFound' không cung cấp sự khớp nào cho chữ ký '(req: Request, res: Response, next: NextFunction): any'

Có ai có gợi ý không? Tôi không chắc mình đang làm sai điều gì.

Câu trả lời #1

RequestHandler là một giao diện đang chỉ định một cái gì đó với chữ ký gọi, mà các lớp không thể triển khai. Bạn muốn một hàm thông thường:

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

Nếu giao diện có new trước chữ ký phương thức, nó sẽ định nghĩa hình dạng của hàm khởi tạo trong lớp của bạn, nhưng trường hợp đó không xảy ra.

Một cách khác để nghĩ về điều này là: khi bạn sử dụng một lớp, bạn đang định nghĩa một hàm mà phải được gọi bằng new. Liệu Express sẽ gọi "new PageNotFound(...)" hay gọi "pageNotFound(...)"?

Như Ryan Cavanaugh, một trong những nhà phát triển TypeScript, đã nói ở đây:

Một cách trang trọng hơn, một lớp triển khai một giao diện là một hợp đồng về những gì một thể hiện của lớp có... - Ryan Cavanaugh 15 Tháng 11 '12 lúc 23:57

Câu trả lời #2

Bạn muốn giữ mọi thứ đơn giản, các lớp là dành cho các đối tượng được sử dụng nhiều hơn một lần. Module express cung cấp cho bạn đối tượng Router với các thuộc tính chính xác.

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; 

Bài viết liên quan