#Get return type of handler in interceptor

1 messages · Page 1 of 1 (latest)

potent violet
#

Is it possible to make a generic interceptor that works similar to a generic pipe where the return type of the handler can be used to transform the response?

For example, look at this Zod pipe:

import { ArgumentMetadata, Injectable, PipeTransform } from '@nestjs/common'
import { z } from 'zod'
import { ZodPipeException } from './zod-pipe.exception'

@Injectable()
export class ZodPipe<T extends z.ZodTypeAny> implements PipeTransform<unknown, z.infer<T>> {
  async transform(value: unknown, metadata: ArgumentMetadata): Promise<z.infer<T>> {
    if (metadata.metatype instanceof z.ZodType) {
      const result = await metadata.metatype.spa(value)

      if (!result.success) throw new ZodPipeException(result.error)

      return result.data
    }

    return value
  }
}

I would like to make a similar interceptor that will parse the returned values from a controller method

gritty ledge
#

It's not really possible because Typescript's reflection system doesn't work well with generics, which is what most controller return types are (due to async methods). You could set your own metadata and read that from the interceptor. You'd essentially be double declaring the return, once for the interceptor, once for Typescript. Or you could make a class that holds a reference to the schema and make sure to return instances of classes for that reason

potent violet
#

Got it. I was trying to avoid the two sources of truth, in the same way the pipe can do that with just the argument type definition. But I guess it's an inherent limitation of TS's reflection system