Aumento de módulos en TypeScript

Antes de adentrarnos en la ampliación de módulos, veamos algunos principios de fusión de TypeScript que resultarán útiles a medida que avancemos.

En esta publicación, hablamos sobre la fusión de interfaces con interfaces. Además, también podemos fusionar interfaces con clases. Veamos un ejemplo.

class Food {  cheese: string;}interface Food {  bacon: string;}const food  = new Food();food.bacon = "nice bacon";food.cheese = "sweet cheese";console.log(food); // {bacon: "nice bacon", cheese: "sweet cheese"}

En nuestro ejemplo anterior, podemos ver que la foodvariable contiene tanto bacony cheesecomo aunque solo cheesese declaró en la Foodclase. Esto se debe a que la interfaz se fusionó con la clase.

Pero ¿qué pasa si nuestra interfaz contiene un método, por ejemplo,bake

class Food {  cheese: string;}interface Food {  bacon: string;  bake(item: string);}const food  = new Food();food.bake("cake"); // Error: food.bake is not a function

Aunque el bakemétodo se mostrará en la foodvariable con la ayuda de intelliSense, debido a que la clase Food y la interfaz Food se fusionarán, llamar al bakemétodo generará un error porque las interfaces solo contienen declaraciones, pero no implementaciones. Para resolver esto, podemos agregar la implementación de bakeal Foodprototipo.

Food.prototype.bake = (item) = console.log(item);

Ahora llamar al bakemétodo funcionará.

food.bake("cake"); // cake

Ingresar al módulo de ampliación

La ampliación de módulos nos ayuda a ampliar las funcionalidades de bibliotecas de terceros a las que quizás no tengamos acceso o a clases en otros archivos.

Digamos que tenemos una Petclase con una namepropiedad y feedun método.

mascota.ts

export class Pet {  name: string;  feed(feedType: string) {    console.log(feedType);  }}

Luego decidimos importar esta clase a nuestro index.tsarchivo, pero en lugar de usar solo los métodos y propiedades de la Petclase, queremos agregar más funcionalidades. Podemos hacerlo usando module augmentation .

Primero, importamos nuestra Petclase a nuestro index.tsarchivo.

índice.ts

import { Pet } from "./pet";

./petes un módulo. Para poder extenderlo, debemos declarar un módulo con el mismo nombre y en ese módulo, declararemos una interfaz con el mismo nombre que la clase que estamos intentando extender. En la interfaz, incluiremos las propiedades y métodos que queremos agregar a la clase extendida.

índice.ts

declare module "./pet" {  interface Pet {    age: number;    walk(location: string);  }}

TypeScript fusionará tanto la Pet clase como la Pet interfaz porque se pueden encontrar en el mismo ./petmódulo.

Pero eso no es todo. Recuerda que expliqué que las interfaces no contienen la implementación de los métodos sino solo sus declaraciones. Por ese motivo, agregaremos la implementación del walkmétodo al prototypeof Pet.

Pet.prototype.walk = (location:string) = `Likes to walk in the ${location}`

Ahora podemos llamar a los métodos y propiedades que se encuentran en la Petclase y a la interfaz recién declarada Pet.

índice.ts

const pet = new Pet();pet.name = "Looty";pet.age = 3;pet.feed("bacon"); // baconconsole.log(pet.name = "Looty"); // Lootyconsole.log(pet.age = 3); // 3console.log(pet.walk("park")); // Likes to walk in the park

Ahora quizás te preguntes, en lugar de declarar una interfaz y luego agregar la implementación del walkmétodo al Petprototipo, ¿por qué no declaramos simplemente una clase con el mismo nombre para que cuando se inicialice la clase, tengamos métodos de ambas clases?

La respuesta es que TypeScript no permite fusionar clases, por lo que no podemos crear dos o más clases con el mismo nombre. Si quieres fusionar clases, existe una solución alternativa que utiliza los mixins de TypeScript que se comentan en esta publicación o puedes usar una biblioteca que creé solo para eso.

Eso es todo. Espero que te haya resultado útil.

SUSCRÍBETE A NUESTRO BOLETÍN 
No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir

Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion