es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Función genérica de TypeScript que no reconoce los guardias de tipo con ts-node.

Estoy tratando de implementar una función de validación genérica. A continuación se muestra una versión mínima muy simple del código:

import Ajv, { JSONSchemaType } from 'ajv'

export function validate<t>(body: string, schema: JSONSchemaType<t>): T {
  const ajv = new Ajv({ allErrors: true })
  const validateSchema = ajv.compile(schema)

  const parsed: unknown = JSON.parse(body)

  if (validateSchema(parsed)) { // <-- este es un guardia de tipo para el tipo T
    return parsed               // <-- VS code reconoce esto como tipo T
  } else {
    throw new Error(`No se pudo validar ${parsed}.`)
  }
}

Cuando intento ejecutar este código a través de ts-node, muestra el siguiente error:

‘T’ podría instanciarse con un tipo arbitrario que podría no estar relacionado con ‘unknown’.

Sin embargo, el motor de inferencia de TypeScript en VS code reconoce correctamente el guardia de tipo.

Captura de pantalla de VS code mostrando el guardia de tipo funcionando correctamente.

De hecho, si muevo ese código a una carpeta donde Ajv no está resuelto (y por lo tanto, el guardia de tipo no es reconocido), VS code me muestra el mismo error que ts-node.

¿Cómo puedo hacer que ts-node reconozca el guardia de tipo? ¿Es esto un bug de ts-node?

Tags:  , ,

Answer

  1. Avatar for davy.ai

    El mensaje de error de ts-node no es un error, pero indica que la seguridad del tipo no se está aplicando en tiempo de ejecución. Esto se debe a que ts-node es una herramienta en tiempo de ejecución que solo transpila TypeScript a JavaScript sobre la marcha, pero no proporciona verificaciones de seguridad de tipos como lo hace el compilador de TypeScript.

    Una solución para aplicar seguridad de tipos en tiempo de ejecución podría ser utilizar un validador de esquemas en tiempo de ejecución como ajv para validar los datos de entrada según el esquema definido antes de devolver los datos analizados. Esto garantizaría que solo se devuelvan datos válidos según el esquema, independientemente de la comprobación de guarda de tipos.

    Aquí tienes un ejemplo de cómo se podría implementar esto en la función validate:

    import Ajv, { JSONSchemaType } from 'ajv';
    
    export function validate<t>(body: string, schema: JSONSchemaType<t>): T {
      const ajv = new Ajv({ allErrors: true });
      const validateSchema = ajv.compile(schema);
    
      const parsed: unknown = JSON.parse(body);
    
      if (!validateSchema(parsed)) {
        throw new Error(`No se pudo validar ${parsed}.`);
      }
    
      return parsed as T;
    }
    

    En este ejemplo, si los datos de entrada no coinciden con el esquema, se lanzará un error en lugar de devolver datos potencialmente inválidos. Además, dado que la instrucción return ahora está obligada a devolver el tipo T, la seguridad del tipo se está aplicando también en tiempo de ejecución.

    En general, es importante recordar que TypeScript proporciona verificaciones de seguridad de tipos en tiempo de compilación, y ts-node no es un sustituto de eso. Sin embargo, con algunas comprobaciones adicionales en tiempo de ejecución a través de herramientas como ajv, es posible garantizar la seguridad del tipo también en tiempo de ejecución.

Comments are closed.