Mi experiencia creando mi primera aplicación en TypeScript.
¡Hola amigos y amigas! Hoy quiero compartir con ustedes mi emocionante viaje al desarrollar mi primera aplicación de consola en TypeScript. Si bien esta aplicación puede parecer simple, fue un desafío para mí y me ayudó a mejorar mis habilidades en el manejo de objetos en programación.
Antes de comenzar, quiero mencionar que este artículo está dirigido a personas que ya tienen conocimientos en el desarrollo de aplicaciones y están familiarizadas con al menos un lenguaje de programación.
Inicio: Preparando el entorno de desarrollo
El primer paso para iniciar mi proyecto fue preparar mi entorno de desarrollo. Para ello, creé mi archivo package.json
, que es fundamental para iniciar un proyecto en Node.js. Aquí está el contenido de mi archivo package.json
:
{
"name": "project",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"deploit": "gh-pages -d rules",
"dev": "npx ts-node index.ts",
"start": "node rules/index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "<name autor>",
"license": "ISC",
"devDependencies": {
"gh-pages": "^5.0.0",
"ts-node": "^10.9.1",
"typescript": "^5.1.3"
}
}
Una vez que creé y ejecuté el archivo package.json
, fue necesario instalar las bibliotecas que utilizaría en mi proyecto. En este caso, instalé las siguientes bibliotecas: gh-pages
(para publicar mi sitio en GitHub Pages), ts-node
(para ejecutar mi código en modo de desarrollo) y typescript
(el propio TypeScript). Utilicé el siguiente comando para instalar las bibliotecas:
npm install --save-dev <nombre de la biblioteca>
Con las bibliotecas instaladas, pasé al último paso de la configuración: el archivo tsconfig.json
. Aquí está la configuración que utilicé:
{
"compilerOptions": {
"target": "es6",
"experimentalDecorators": true,
"module": "commonjs",
"outDir": "./dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
Con mi entorno de desarrollo configurado correctamente, estaba listo para comenzar a construir mi aplicación.
Construyendo el objeto central: Calculeitor
En el corazón de mi aplicación se encontraba el objeto Calculeitor
, que se encargaría de realizar todos los cálculos necesarios. Aquí está el código de la clase Calculeitor
:
export class Calculeitor
{
constructor() {}
/**
* Calcula la suma de los números en un arreglo.
* @param numbers - Arreglo de números.
* @returns La suma de los números.
*/
public suma(numbers: number[]): number
{
let sum = 0;
for (const num of numbers) {
sum += num;
}
return sum;
}
/**
* Realiza la resta de un número y los elementos de otro arreglo.
* @param number - Número inicial.
* @param numberN - Arreglo de números a restar.
* @returns El resultado de la resta.
*/
public resta(number: number, numberN: number[]): number
{
let sum = 0;
for (const num of numberN) {
sum += num;
}
const resta = number - sum;
return resta;
}
/**
* Realiza la división entre dos números.
* @param numberi - Dividendo.
* @param numberb - Divisor.
* @returns El resultado de la división.
*/
public division(numberi: number, numberb: number): number
{
const div = numberi / numberb;
return div;
}
/**
* Realiza la multiplicación de varios números.
* @param numbers - Arreglo de números a multiplicar.
* @returns El resultado de la multiplicación.
*/
public multiplicacion(numbers: number[]): number
{
let mul = 1;
for (const num of numbers) {
mul *= num;
}
return mul;
}
/**
* Calcula la potencia de un número elevado a un exponente.
* @param number - Número base.
* @param exponente - Exponente.
* @returns El resultado de la potencia.
*/
public potencia(number: number, exponente: number): number
{
const expon = number ** exponente;
return expon;
}
/**
* Calcula la raíz cuadrada de un número.
* @param numero - Número.
* @returns La raíz cuadrada del número.
* @throws Error si se intenta calcular la raíz cuadrada de un número negativo.
*/
public raiz(numero: number): number
{
if (numero < 0) {
throw new Error("No se puede calcular la raíz cuadrada de un número negativo.");
}
const raiz = Math.sqrt(numero);
return raiz;
}
}
En esta clase, implementé varios métodos para realizar operaciones matemáticas como suma, resta, división, multiplicación, potencia y raíz cuadrada. Cada método realiza los cálculos correspondientes y devuelve el resultado.
Diagrama de flujo y construcción de la aplicación
Con mi objeto Calculeitor
listo, comencé a construir mi aplicación en consola. Aquí está el diagrama de flujo que seguí:
- Importé el módulo
readline
para leer la entrada del usuario. - Importé la clase
Calculeitor
desde el archivo donde definí mi objeto. - Definí una función
printMenu
para mostrar las opciones del programa. - Definí una función
createInterface
para crear la interfaz de lectura de entrada y escritura de salida. - Definí una función
readNumbers
para leer una serie de números separados por espacios. - Definí una función
waitForKey
para esperar a que el usuario presione una tecla antes de continuar. - Definí una función
readNumber
para leer un número individual. - Finalmente, implementé la función principal
calculate
, que ejecutaría la lógica de la calculadora.
Aquí está el código que implementé para la aplicación:
import * as readline from 'readline';
import { Calculeitor } from './calculador/calculetor';
// Home
function printMenu() {
console.log("=== Calculadora ===");
console.log("1. Suma");
console.log("2. Resta");
console.log("3. División");
console.log("4. Multiplicación");
console.log("5. Exponencial");
console.log("6. Raíz cuadrada");
console.log("0. Salir");
}
// Conexión
function createInterface() {
return readline.createInterface({
input: process.stdin,
output: process.stdout
});
}
// Lectura de parámetros
function readNumbers(): Promise<number[]> {
return new Promise<number[]>(async (resolve) => {
const rl = createInterface();
rl.question("Ingresa los números separados por espacios: ", (input: string) => {
rl.close();
const numbers = input.split(" ").map(Number);
resolve(numbers);
});
});
}
function waitForKey(): Promise<void> {
return new Promise<void>(async (resolve) => {
const rl = createInterface();
rl.question("Presiona cualquier tecla para continuar...", () => {
rl.close();
resolve();
});
});
}
function readNumber(name: string): Promise<string> {
const txt = name;
return new Promise<string>(async (resolve) => {
const rl = createInterface();
rl.question(txt, (input: string | PromiseLike<string>) => {
rl.close();
resolve(input);
});
});
}
// Función calculadora
async function calculate() {
// Variables globales
const calc = new Calculeitor();
let option = -1;
while (option !== 0) {
// Home
printMenu();
// Primera pregunta
option = parseInt(await readNumber("Ingresa una opción: "));
// Opción
switch (option) {
case 1: {
const numbers: number[] = await readNumbers();
const result = calc.suma(numbers);
console.log(`El resultado de la suma es: ${result}`);
await waitForKey();
break;
}
case 2: {
const number = await readNumber("Ingresa el primer número: ");
const numbers: number[] = await readNumbers();
const result = calc.resta(parseFloat(number), numbers);
console.log(`El resultado de la resta es: ${result}`);
await waitForKey();
break;
}
case 3: {
const numberi = parseInt(await readNumber("Ingresa el dividendo: "));
const numberb = parseInt(await readNumber("Ingresa el divisor: "));
const result = calc.division(numberi, numberb);
console.log(`El resultado de la división es: ${result}`);
await waitForKey();
break;
}
case 4: {
const numbers: number[] = await readNumbers();
const result = calc.multiplicacion(numbers);
console.log(`El resultado de la multiplicación es: ${result}`);
await waitForKey();
break;
}
case 5: {
const number = parseInt(await readNumber("Ingresa el número base: "));
const exponente = parseInt(await readNumber("Ingresa el exponente: "));
const result = calc.potencia(number, exponente);
console.log(`El resultado de la exponenciación es: ${result}`);
await waitForKey();
break;
}
case 6: {
const numero = parseInt(await readNumber("Ingresa el número: "));
const result = calc.raiz(numero);
console.log(`La raíz cuadrada es: ${result}`);
await waitForKey();
break;
}
case 0: {
console.log("Saliendo de la calculadora...");
break;
}
default: {
console.log("Opción inválida. Inténtalo de nuevo.");
break;
}
}
}
}
calculate();
Este código implementa la funcionalidad principal de la calculadora en consola. Al ejecutar el programa, se muestra un menú con opciones para realizar diferentes operaciones matemáticas. Dependiendo de la opción seleccionada, el programa solicita los valores necesarios al usuario, realiza el cálculo utilizando el objeto Calculeitor
y muestra el resultado.
Retos y dificultades
Durante el desarrollo de este proyecto, enfrenté varios retos y dificultades. Uno de los desafíos fue configurar correctamente el entorno de desarrollo, especialmente al trabajar con TypeScript. Tuve que asegurarme de instalar las dependencias necesarias y configurar adecuadamente los archivos package.json
y tsconfig.json
. Afortunadamente, consulté la documentación oficial y algunos recursos en línea que me ayudaron a superar estos obstáculos.
Otro desafío fue implementar la lógica de la calculadora en sí. Aunque las operaciones matemáticas básicas no eran complicadas, tuve que pensar en cómo interactuar con el usuario a través de la consola y cómo validar las entradas para evitar errores. Además, la implementación de la función de raíz cuadrada requirió un manejo especial para evitar errores con números negativos.
Conclusiones y próximos pasos
En resumen, crear mi primera aplicación en TypeScript fue una experiencia emocionante y enriquecedora. Aprendí mucho sobre el manejo de objetos en TypeScript, la configuración del entorno de desarrollo y la interacción con el usuario en la consola. Aunque esta aplicación es relativamente simple, me proporcionó una base sólida para proyectos futuros y me ayudó a mejorar mis habilidades en programación.
Para los próximos pasos, planeo explorar más a fondo las capacidades de TypeScript, incluyendo conceptos avanzados como los decoradores y los tipos genéricos. También quiero ampliar la funcionalidad de mi calculadora, agregando más operaciones matemáticas y mejorando la interfaz de usuario. Con el tiempo, espero poder convertir esta aplicación de consola en una aplicación web interactiva.
¡Gracias por acompañarme en este viaje de desarrollo y espero que mi experiencia te inspire a crear tus propias aplicaciones con TypeScript!