Wyszukiwanie w witrynie

Jak dodać funkcję rozszerzającą do odpowiedzi express w TypeScript?


Chcę rozszerzyć Response w Express o niestandardowe funkcje. Chcę dodać funkcję:

sendError(statusCode: number, errorMessage: string)

tak, abym mógł to wywołać wszędzie jak

response.sendError(500, "Unable to process this request at the moment.")

Czy możesz mi powiedzieć, jak to osiągnąć? Przejrzałem kilka innych pytań, takich jak metoda rozszerzeń dla liczby w TypeScript, ale nadal mam pewne wątpliwości:

  1. Jak mogę rozszerzyć funkcję na Response, gdy nie ma ona prototypu?
  2. Gdzie umieszczam definicję rozszerzonej funkcji? Czy mogę zrobić osobny plik zawierający wszystkie definicje?
  3. Czy muszę przypisywać tę funkcję do każdego obiektu Response, aby ją używać, czy mogę po prostu zdefiniować ją raz i używać na wszystkich obiektach response w całym moim projekcie?

Proszę, pomóż mi z tym. Jestem nowy w TypeScript, więc proszę wybacz wszelkie błędy, które mogłem popełnić w moim pytaniu :)

Odpowiedź #1

Express używa własnego prototypu zarówno dla obiektów żądania, jak i odpowiedzi, który dziedziczy z wersji http.

Możesz znaleźć prototyp odpowiedzi Express w obiekcie express jako express.response.

W zwykłym JavaScripcie to będzie działać:

const express = require('express');
const app = express();

// add my own method to the response prototype so it can be used
// by any route
express.response.mySend = function(data) {
    // this here is the live res object for this particular request
    console.log("about to send data with my custom response method");
    this.send(data);
}

app.get("/", (req, res) => {
    res.mySend("hello");
});

app.listen(80);

Aby to zadziałało w TypeScript, będziesz potrzebować odpowiednich powiązań typów dla obiektu express.response, które pozwolą ci to zrobić. Nie jestem osobą znającą TypeScript, więc tę część będziesz musiał obsłużyć sam.

Do Twojej informacji, obiekt żądania to express.request i można go używać w podobny sposób.


Możesz również dodać swoje własne metody w middleware w ten sposób, ale przypuszczam, że jest to nieco mniej wydajne (jeśli to w ogóle ma znaczenie):

const express = require('express');
const app = express();

// add my own method to the response prototype so it can be used
// by any route
app.use((req, res, next) => {
    res.mySend = function(data) {
        // this here is the live res object for this particular request
        console.log("about to send data with my custom response method");
        this.send(data);
    });
    next();
});

app.get("/", (req, res) => {
    res.mySend("hello");
});

app.listen(80);

Odpowiedź #2

Chcesz stworzyć własną definicję i użyć funkcji w TypeScript zwanej Łączeniem Deklaracji.

Metoda 1: Middleware

Możesz użyć middleware i dodać deklaracje dla nowych metod

  1. Utwórz folder middlewares i middlewares/typings

  2. Utwórz plik middlewares/typings/express-extended-response.d.ts

    declare namespace Express {
      export interface Response {
        sendError(statusCode: number, errorMessage: string): void
      }
    }
    
  3. Utwórz plik middlewares/express-extended-response.ts

    import { Request, Response, NextFunction } from 'express'
    
    export function extendedResponse(req: Request, res: Response, next: NextFunction) {
      res.sendError = function (statusCode, errorMessage) {
        this.status(statusCode).send(errorMessage)
      }
      next()
    }
    
  4. W twoim app.ts lub index.ts

    import express from 'express'
    import { extendedResponse } from './middlewares/express-extended-response'
    
    const app = express()
    app.use(extendedResponse)
    // From now on you can use the 'sendError' method on every object of type Response
    
    app.get('/', (req, res) => {
      res.sendError(404, 'Not found')
    })
    

Metoda 2: Dodaj funkcję do express.response

Możesz dodać metody do obiektu express.response

  1. Utwórz folder typings

  2. Utwórz plik typings/express-extended-response.d.ts

    declare namespace Express {
      export interface Response {
        sendError(statusCode: number, errorMessage: string): void
      }
    }
    
  3. W twoim app.ts lub index.ts

    import express from 'express'
    
    const app = express()
    
    app.response.sendError = function (statusCode, errorMessage) {
      this.status(statusCode).send(errorMessage)
    }
    
    app.get('/', (req, res) => {
      res.sendError(404, 'Not found')
    })
    

ts-node

jeśli chcesz używać ts-node, musisz określić flagę --files lub uwzględnić ją w swoim tsconfig.json

ts-node --files app.ts
ts-node --files index.ts
tsconfig.json
{
  "ts-node": {
    "files": true
  },
  "compilerOptions": {
    "esModuleInterop": true,
     ...
  }
}
ts-node app.ts
ts-node index.ts

Demonstracja

Powiązane artykuły