Bienvenidos sean a este post, hoy repasaremos uno de los decoradores.
En el post anterior vimos como son los decoradores en las clases y tomamos principalmente al de clases para ver los ejemplos. Dijimos que cada decorador es una funcion que en base a sus argumentos y tipos definen de que tipo seran. Si vemos en el caso de las clases este debe tener un argumento de tipo funcion, el cual estara relacionado al constructor de la clase. Pasemos a verlo en accion mediante algunos ejemplos, comenzando con el primero:
function decorarClase(constructor: Function) {
console.log('constructor: ' + constructor);
}
@decorarClase
class claseDecorada {
constructor(id: number) {}
}
Lo primero es nuestra funcion decoradora la cual mostrara un mensaje indicando cual es el constructor de nuestra clase al momento de ser invocado. La invocamos y tenemos una clase donde definimos un constructor que puede recibir un valor numerico para usar como id (recuerden que de esta forma genera automaticamente la propiedad). Compilemos y veamos como es la salida:
$ node decorar.js
constructor: class claseDecorada {
constructor(id) { }
}
$
Aqui nos devolvio la clase y el constructor de esta, hasta aqui es lo mismo que vimos en el post anterior donde obtendremos una notificacion cada vez que lo invocamos. Vamos a utilizarlo en un ejemplo mas practico y para ello debemos tomar el codigo anterior y modificarlo de la siguiente manera:
type Ctr = { new (...args: any[]):any }
function decorarClase<T extends Ctr>(ClaseBase: T) {
return class extends ClaseBase {
id: number = 1;
nombre: string = "Anonimo";
};
}
@decorarClase
class claseDecorada {
constructor(public usuario: string) {}
}
let obj = new claseDecorada("tinchicus");
console.log(JSON.stringify(obj));
Este ejemplo sirve para agregar nuevos elementos en una clase pero de una forma muy particular, comencemos por el principio. Primero definiremos un alias para un tipo nuevo, este es muy particular porque lo usaremos para recibir al constructor de cualquier clase, recuerden que es la forma de usarlo como decorador de clases, y para este caso recibiremos todos los argumentos mediante el operador de propagacion y mediante el tipo any recibiremos cualquiera y asi como devolveremos cualquiera. Con nuestro receptor del constructor creada podemos pasar al siguiente tema. Este va a ser la funcion que usaremos de decoracion y usaremos un tipo generico que extendera o sera heredero del constructor, es decir la clase que decoramos, y como argumento recibiremos a la clase base. La magia de la funcion es que devolvera un clase que extiende a la clase informada, es decir sera hija de esta, y ahi agregaremos dos propiedades mas. Luego tenemos una clase donde la decoramos con la funcion anterior y en esta solo tenemos un constructor donde crearemos e iniciaremos esta propiedad.
Nuestro siguiente paso sera crear un nuevo objeto de este tipo con el dato solicitado y al final mostraremos todo el contenido del objeto creado. Compilemos y veamos la salida:
$ node decorar.js
{"usuario":"tinchicus","id":1,"nombre":"Anonimo"}
$
Como pueden ver funciono pero a medias, si intentamos obtener alguno de los datos de la siguiente forma:
console.log("id: " + obj.id);
Nos devolvera el siguiente error::
error TS2339: Property 'id' does not exist on type 'claseDecorada'.
Si bien vemos que existe en el objeto no significa que exista en la clase y este es un inconveniente de typescript bien conocido. Esto es principalmente porque para lograr el objetivo debemos transformar a estos datos parte de los herederos de la clase que decoramos por lo tanto desde esta no podemos acceder. Se puede generar un codigo para recuperar un elemento particular pero en general como estos objetos se usan para cargar en una base de datos nos sera mas util trabajarlo de esta manera.
Tengan en cuenta que en mucha documentacion encontraran un opcion para hacer esto, esta es prototype. En algun momento funciono pero hoy en dia dejo de funcionar, no pude encontrar ninguna documentacion hablando si se desecho o se anulo por alguna razon. En todo caso esta solucion que les comente anteriormente esta extraido directamente del manual de typescript y es la recomendada por ellos.
En resumen, hoy hemos visto al decorador de clases, que es, para que sirve, como se utiliza, un ejemplo practico y mas veridico para ver como trabaja y como se debe usar y el inconveniente que tendremos, espero les haya resultado de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.50
