GOOGLE ADS

jueves, 28 de abril de 2022

¿Cómo logran las bibliotecas mecanografiadas leer tipos en tiempo de ejecución?

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

Regla de Firestore para acceder a la generación de subcolección Permisos faltantes o insuficientes

Tengo problemas con las reglas de Firestore para permitir el acceso a algunos recursos en una subcolección. Tengo algunos requests document...