He estado experimentando con Typescript Decorators recientemente para intentar resolver un "problema" que tengo dentro de mi aplicación. Estoy usando un puente JS para enviar código TS tanto a Android como a iOS, y en este momento declaramos funciones como esta:
índice.js
import foo from './bar' global.App = function() { this.foo = foo; }; Lo anterior hará que la función foo esté disponible en el lado nativo del puente.
Quería escribir un decorador para aplicar en ese método foo que se "registraría" en la global.App , pero fallé en esa tarea.
Aquí está el decorador que funciona:
export const Task = (target, propertyKey, descriptor) => { let originalMethod = descriptor.value; descriptor.value = (...args) => originalMethod.apply(target, args); if (!global.App) { global.App = function () { this.foo = descriptor.value; }; } return descriptor; } ¿Cómo podría agregar otro método a esa función global.App ?
En primer lugar, el método foo solo se agrega una vez porque la primera vez que se llama al decorador se define global.App y la rama que agrega foo a global.App nunca se vuelve a ingresar.
En segundo lugar, global.App y foo se sobrescribirían cada vez y no se mantendrían a través de llamadas repetidas al decorador.
Agregar otra rama que maneje agregar el método después de la primera llamada y asigne dinámicamente el nombre del método, que creo que se le da al decorador en propertyKey , permitiría agregar múltiples métodos.
export const Task = (target, propertyKey, descriptor) => { let originalMethod = descriptor.value; descriptor.value = (...args) => originalMethod.apply(target, args); if (!global.App) { global.App = function () { this[propertyKey] = descriptor.value; }; } else { global.App[propertyKey] = descriptor.value; } return descriptor; }Algo como esto podría funcionar.
Después de deambular por SO durante algún tiempo, encontré una solución para esto ... tal vez no tenga el conocimiento de TS/JS para saber exactamente qué quería hacer aquí, pero de todos modos, mi solución fue registrar cada tarea decorada y luego en index.js obtengo esas tareas y las registro en la función global.App .
Algo como esto
tarea.ts
export const TaskRegistry = {}; export const Task = (target, propertyKey, descriptor) => { const originalMethod = descriptor.value; descriptor.value = (...args) => originalMethod.apply(target, args); TaskRegistry[propertyKey] = descriptor.value; return descriptor; };índice.js
// eslint-disable-next-line func-names global.App = function () { // eslint-disable-next-line consistent-this const self = this; Object.keys(TaskRegistry).forEach((key) => { self[key] = TaskRegistry[key]; }); }