Solicitação expressa digitada e resposta com TypeScript

Foto de Jefferson Santos no Unsplash

Escrever código com TypeScript é ótimo, mas há alguns lugares no código onde é realmente complicado deixar o TypeScript brilhar. Um deles é ao definir rotas no Express.

Este artigo descreve algumas das maneiras de adicionar TypeScript aos objetos Express.Requeste Express.Response.

Configurando o Express

Vamos fazer o básico primeiro.

import Express from 'express';
import http from 'http';
let app: Express.Application | undefined = undefined;
export function InitializeExpress(port = 3001): void {
app = Express();
    app.use(Express.urlencoded({ extended: true }));
app.get('/', function (_req: Express.Request, res: Express.Response) {
        res.status(200).json({
            "Foo": "Bar",
             "Time": new Date().toISOString()
        });
    });
// Add 404 handler
   app.use(function (_req: Express.Request, res: Express.Response) {
      res.status(404).send("Not found");
   });
// Start server (app.listen can also be used)    
   http.createServer(app).listen(port, () =>  
    console.log(`Running at http://localhost:${port}/`));
}

{"Foo":"Bar","Time":"2021-09-21T19:32:15.091Z"}

O objeto Express.Request é definido como:

interface e.Request<P = ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = QueryString.ParsedQs, Locals extends Record<string, any> = Record<string, any>>

export interface TypedRequestBody<T> extends Express.Request {
    body: T
}

app.post('/login', function (req: TypedRequestBody<{ username: string, password: string }>, res: Express.Response) {
const success = req.body.username === "foo"
                    && req.body.password === "bar";
res.status(200).json({ "Success": success });
});

Express.Request .query

Modificar o queryem Express.Request é um pouco mais complicado, porque o Express usa tipos de express-serve-static-core, que por sua vez o Express não expõe. Portanto, a única maneira de obter os tipos adequados é import { Query } from 'express-static-serve-core';. A solução é fazer:

import { Query } from 'express-serve-static-core';
export interface TypedRequestQuery<T extends Query> extends Express.Request {
query: T
}

app.get('/article/:id', function (req: TypedRequestQuery<{ id: string }>, res: Express.Response) {
const id = req.query.id;
// Fetch from database here and return article
res.status(200).json({ ID: id });
});

Vamos fazer outro tipo, onde ambosbody e querypode ser digitado:

export interface TypedRequest<T extends Query, U> extends Express.Request {
    body: U,
    query: T
}

app.put('/article/:id', function (req: TypedRequest<{ id: string }, { name: string }>, res: Express.Response) {
console.log(`Updating article ${req.query.id}`);
        console.log(`setting name to ${req.body.name}`);
        res.status(200).json({ Success: true });
});

O TypeScript não existe no tempo de execução, então até mesmo o código está configurado para esperar uma carga útil de:

{ username: string, password: string }

{ username: undefined, password: ["Hello", "World"] }

PS:

Se você deseja gerar funções de validador automaticamente a partir de interfaces / tipos TypeScript, leia este artigo: https://javascript.plainenglish.io/how-to-automatically-convert-typescript-types-to-runtime-validators-5b06ee269b13

Express.Response

Novamente o Express usa tipos de express-serve-static-core:

import { Send } from 'express-serve-static-core';

export interface TypedResponse<ResBody> extends Express.Response {
json: Send<ResBody, this>;
}

app.get('/ping', function (_req: Express.Request, res: TypedResponse<{ Pong: string }>) {
res.status(200).json({ "Pong": new Date().toISOString() });
});

Código-fonte de demonstração?

https://github.com/tomnil/typedexpress

Aproveitar :)

Mais conteúdo em plainenglish.io

Suggested posts

Encontrar informações sobre nomes de domínio

Um trecho de Small, Sharp Software Tools por Brian P. Hogan

Encontrar informações sobre nomes de domínio

Quando você faz uma solicitação para facebook.com, seu computador procura o nome de domínio para traduzir esse nome de domínio em um endereço IP para que seu computador possa fazer essa conexão.

A revolução sem código: liberando a prosperidade dos negócios com Webflow, Framer, Bubble.io,

A revolução sem código: liberando a prosperidade dos negócios com Webflow, Framer, Bubble.io,

Embarque em uma emocionante jornada de inovação e sucesso enquanto explora o potencial inexplorado dessas surpreendentes plataformas sem código. Deixe-me compartilhar uma história com você sobre Sapna, uma notável empresária.

Related posts

A arte é sempre apolítica?

A arte é sempre apolítica?

Ontem, fechamos a porta do Festival Eurovisão da Canção deste ano com uma brilhante e caótica grand finale, onde a cantora sueca Loreen levou para casa o troféu, tornando-se a primeira mulher a vencer duas vezes e trazendo a coroa de volta para a Suécia 50 anos depois que o ABBA venceu a competição com “Waterloo”. Eles se tornaram um dos maiores artistas do cânone da música pop.

Journal Ouvert

Journal Ouvert

Diário aberto: uma foto por dia. Sempre fui fascinado por histórias.

Dois anos em design - O bom, o mau e o feio…

Dois anos em design - O bom, o mau e o feio…

“Ei, Siri, toque Me Dive, de Olivia Dean.” Era maio de 2021 quando comecei meu estágio na Future Academy Africa em Akure, Nigéria.

O desafio de leitura Goodreads é tóxico

O desafio de leitura Goodreads é tóxico

A coceira na minha mão aumentou enquanto eu negociava com o livreiro local por mais um livro. Este livro, como o resto que comprei recentemente, encontraria seu trono na minha pilha 'To Be Read' (TBR); e ainda assim, eu comprei.