paint-brush
Creación de métodos de extensión usando TypeScriptpor@msarica
17,289 lecturas
17,289 lecturas

Creación de métodos de extensión usando TypeScript

por Mehmet2m2020/01/08
Read on Terminal Reader
Read this story w/o Javascript

Demasiado Largo; Para Leer

Creando métodos de extensión usando Typescript usando decoradores. La característica del método de extensión de C# es una solución alternativa. Estamos agregando la función al prototipo de la pasada en clase. Este truco no funcionará en la mayoría de las bibliotecas de terceros, suponiendo que estén protegidas contra la contaminación de prototipos. La belleza de los métodos de extensión es que deberían funcionar en clases sobre las que no tenemos ningún control. Entonces, este truco no funcionará en la mayoría de las bibliotecas de terceros. (https://stackblitz.com/cms/TypeScript/issues/9)

Companies Mentioned

Mention Thumbnail
Mention Thumbnail
featured image - Creación de métodos de extensión usando TypeScript
Mehmet HackerNoon profile picture

Me gusta mucho la característica del método de extensión de C#. Estaba tratando de experimentarlo en Typescript con decoradores.

 export function extension ( ctr: any ) { let originalFunction: Function ; return function ( target, propertyKey: string , descriptor: PropertyDescriptor ) { originalFunction = descriptor.value; ctr.prototype[propertyKey] = function ( ...args ) { return originalFunction( this , ...args); } } }

Creé una fábrica de decoradores llamada

 extension
. Esto toma la clase a la que queremos agregar el método. Esencialmente, lo que queremos es ejecutar este método en cualquier objeto que sea una instancia de "
 ctr
".

Dado que Typescript no nos brinda un concepto de método de extensión de compilación, como solución alternativa, estamos agregando la función al prototipo de la clase pasada.

 export class User { constructor ( public name: string = 'joe', public lastname: string = 'doe' ){} } export class Extensions { @extension(User) static test(user: User){ console .log(user.name , 'this works' ); } @extension(User) static gaveMoney(thisArg: User, amount : number, to : User){ console .log( ` ${thisArg.name} gave ${to.name} \$ ${amount} ` ); } } 
 const user = new User(); const user2 = new User( 'mehmet' , '' ); user.gaveMoney( 10 , user2); user2.gaveMoney( 20 , user);
 user.test();

Como puede ver, los métodos con los que decoramos

 extension
se añaden al prototipo de
 User
clase.

Si está recibiendo un error

 Property 'gaveMoney' does not exist on type 'User'
puede hacer una de las dos cosas siguientes:

 (user as any).gaveMoney( 10 , user2);

o

 export interface User{ test; // adding the name only will fix the error gaveMoney(n: number, u :User) // this will give intellisense }

Problema

Al mutar el prototipo esencialmente estamos contaminando el prototipo. Así que este truco no funcionará en

 frozen
o
 sealed
objetos. Veamos lo siguiente como ejemplo. Congelamos el
 User2
class y su prototipo y obtuve un error porque nuestro método no pudo modificar la clase.

 export class Extensions2 { @extension(User2) static test(user: User2){ console .log(user.name , 'this works' ); } } export class User2 { name = 'john' } Object .freeze(User2); Object .freeze(User2.prototype); const sealedUser = new User2(); sealedUser.test();


Conclusión

Aunque este truco funcionará para nuestro material, probablemente no funcionará en la mayoría de las bibliotecas de terceros, suponiendo que estén protegidas contra la contaminación de prototipos. La belleza de los métodos de extensión es que deberían funcionar en clases sobre las que no tenemos ningún control.

Esperemos que el equipo de Typescript decida agregar esta característica increíble. ( https://github.com/microsoft/TypeScript/issues/9 )

Demostración de este artículo: https://stackblitz.com/edit/ts-ms-extension-methods-experiment?file=index.ts