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
?
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 quets-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
: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 tipoT
, 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 comoajv
, es posible garantizar la seguridad del tipo también en tiempo de ejecución.