En Nest, un pipe es una funcion que puede modificar o validar datos que le pasemos con el objeto de poder mejorar la forma en la que lo manejamos. Veamos este ejemplo.

  @Get('ticket/:num')
  getNumber(@Param('num') param: number) {
    return param + 2;
  }

Parece claro, pero debido a las caracteristicas de JavaScript, este será el output

El param, por mas que nosotros le hayamos dicho que es un number, lo guardará como string porque asi le llega. Entonces, al ser un string, lo va a concatenar en lugar de sumarlo.

El param, por mas que nosotros le hayamos dicho que es un number, lo guardará como string porque asi le llega. Entonces, al ser un string, lo va a concatenar en lugar de sumarlo.

Si queremos modificar el dato para que pueda realizar bien la tarea la funcion, podemos usar un pipe modificador, en este caso uno que lo pase a numero.

  @Get('ticket/:num')
  getNumber(@Param('num', ParseIntPipe) param: number) {
    return param + 2;
  }

Podes ver la cantidad de pipes nativos en Nest acá. Sin embargo, Nest tambien nos permite crear nuestros propios pipes de forma muy sencilla utilizando la terminal. Supongamos este caso

  @Get('greet')
  greet(@Query() query: { name: string; age: number }) {
    return `Hello ${query.name}, you are ${query.age} years old`;
  }

Como vienen de la URL, estos datos van a ser un string, inclusive la edad. Sin embargo, no hay una forma nativa de poder darle el tipo que necesita este objeto, sobre todo el number que es un string aunque querramos que sea number porque viene de la URL. Para eso debemos crear nuestro propio pipe y eso lo hacemos desde la terminal con el comando

nest generate pipe rutaDondeQueremosQueLoCree

Una vez que ejecutamos este comando, automaticamente se creará el pipe en la ruta determinada. Lo creará con su respectivo archivo de testing.

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common';

@Injectable()
export class ValidategreetPipe implements PipeTransform {
  transform(value: any, metadata: ArgumentMetadata) {
    return value;
  }
}

Dentro del transform debemos realizar toda la lógica para poder darle el tipo que nosotros buscamos al objeto que nos llega, en este caso, desde la query. Y como lo ejecutamos? De la misma forma que los pipes nativos

  @Get('greet')
  greet(@Query(CustomPipe) query: { name: string; age: number }) {
    return `Hello ${query.name}, you are ${query.age} years old`;
  }