Cuando el código fuente se compila de mecanografiado a javascript, las anotaciones de tipo se eliminan y no hay forma de verificar el tipo de una variable en tiempo de ejecución.
Sin embargo, hay muchas bibliotecas de mecanografiados que parecen cambiar el comportamiento en función de las anotaciones de tipo de las propiedades de la clase. Por ejemplo, al escribir entidades typeorm, podríamos escribir algo como:
@Entity()
class MyEntity extends BaseEntity {
@Field()
public id: number // automatically infers int database type
@Field()
public description: string // automatically infers varchar or text database type
@Field()
public image: string | null // cannot infer correct type, will throw error
}
También tenemos algo similar con typedi (pasa la referencia correcta a través del constructor), type-graphql (construye el esquema de graphql con el tipo de graphql correcto), etc. Lo entiendo cuando tienes que pasar una función a través de un decorador o algo similar, pero ¿cómo hacer esto? ¿Las bibliotecas infieren tipos solo a partir de anotaciones de tipo?
Solución del problema
Sentí curiosidad y encontré la respuesta en la documentación de TypeORM aquí:
Configuración de mecanografiado
Además, asegúrese de estar utilizando TypeScript versión 4.5 o superior, y de haber habilitado las siguientes configuraciones en tsconfig.json:
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
Sospeché que le dije a TypeScript que proporcionara información de tipo de tiempo de ejecución a los decoradores y, de hecho, lo hace:
Emitir metadatos de decorador
emitDecoratorMetadata
Habilita el soporte experimental para emitir metadatos de tipo para decoradores que funcionan con el módulo reflect-metadata.
Cuando tiene eso habilitado, TypeScript emite llamadas a los decoradores que incluyen información de tipo en tiempo de ejecución. El ejemplo en la documentación es para este código:
class Demo {
@LogMethod
public foo(bar: number) {
// do nothing
}
}
...que emite __decoratey __metadatafunciona, entonces esto:
class Demo {
foo(bar) {
// do nothing
}
}
__decorate([
LogMethod,
__metadata("design:type", Function),
__metadata("design:paramtypes", [Number]),
__metadata("design:returntype", void 0)
], Demo.prototype, "foo", null);
Si miramos tu ejemplo, esto es lo que emite para las llamadas al decorador:
__decorate([
Field(),
__metadata("design:type", Number)
], MyEntity.prototype, "id", void 0);
__decorate([
Field(),
__metadata("design:type", String)
], MyEntity.prototype, "description", void 0);
__decorate([
Field(),
__metadata("design:type", Object)
], MyEntity.prototype, "image", void 0);
MyEntity = __decorate([
Entity()
], MyEntity);
Enlace del patio de recreo
No hay comentarios:
Publicar un comentario