Saltar al contenido principal

Fundamentos y Estilo

1. Reglas de Estilo y Formateo de Código

Regla Principal

Regla: El código JavaScript y TypeScript generado o asistido por la IA debe adherirse estrictamente a las siguientes convenciones de estilo y formateo:

  1. Indentación: Se deben utilizar un (1) espacio por cada nivel de indentación. El uso de tabulaciones está prohibido.
  2. Comillas: Se deben utilizar comillas simples (') para todas las cadenas de texto (strings). Las comillas dobles (") solo se permitirán en contextos donde la especificación del formato lo requiera explícitamente (ej. atributos HTML, JSON). Las plantillas literales (template literals, comillas invertidas `) se deben usar para la interpolación de cadenas o para cadenas multilínea.
  3. Punto y Coma: Se debe incluir un punto y coma (;) al final de cada sentencia ejecutable.
  4. Nomenclatura:
    • Variables y funciones: Deben nombrarse utilizando camelCase (ej. nombreUsuario, calcularTotal).
    • Clases, Interfaces, Tipos (Custom Types) y Enums: Deben nombrarse utilizando PascalCase (ej. GestorArchivos, IUsuario, TipoRespuesta, EstadoPedido).
    • Constantes (valores que no cambian y son significativos, a menudo exportados o globales): Deben nombrarse utilizando UPPER_CASE con guiones bajos para separar palabras (ej. MAX_CONNECTIONS, API_URL).

Contexto y Justificación

Estas convenciones son obligatorias para asegurar la máxima legibilidad, consistencia y mantenibilidad del código. Un estilo uniforme reduce la carga cognitiva al leer y revisar código, facilita la colaboración entre desarrolladores (humanos y IA) y previene errores comunes derivados de la inconsistencia. La IA debe generar código que parezca escrito por un único desarrollador disciplinado y que siga los estándares del proyecto.

Ejemplos y Contraejemplos

Indentación:

  • Correcto:
    function ejemplo(condicion) {
    if (condicion) {
    console.log('Indentación correcta con 2 espacios.');
    }
    }
  • Incorrecto:
    function ejemplo(condicion) {
    if (condicion) {
    console.log('Indentación incorrecta con 4 espacios.'); // INCORRECTO
    }
    }
    function otroEjemplo(condicion) {
    if (condicion) { // INCORRECTO: Tabulación
    console.log('Indentación incorrecta con tabulación.');
    }
    }

Comillas:

  • Correcto:
    const mensajeSimple = 'Hola mundo';
    const nombre = 'Alice';
    const saludoComplejo = `Hola, ${nombre}! Bienvenida.`;
    const parrafo = `Esta es una cadena
    que ocupa múltiples
    líneas.`;
  • Incorrecto:
    const mensajeDoble = "Hola mundo"; // INCORRECTO
    const interpolacionConConcatenacion = 'Hola, ' + nombre + '! Bienvenida.'; // INCORRECTO
    const multilineaConEscape = "Linea 1\nLinea 2"; // INCORRECTO

Punto y Coma:

  • Correcto:
    const x = 10;
    console.log(x);
  • Incorrecto:
    const x = 10 // INCORRECTO
    console.log(x) // INCORRECTO

Nomenclatura:

  • Correcto:
    const DEFAULT_TIMEOUT = 5000;
    let contadorVisitas = 0;
    function procesarArchivo(nombreArchivo) { /* ... */ }
    class AdministradorTareas { /* ... */ }
    interface OpcionesConfig { /* ... */ }
    type IdUsuario = string | number;
    enum NivelAcceso { Lector, Editor, Admin }
  • Incorrecto:
    const default_timeout = 5000; // INCORRECTO
    let ContadorVisitas = 0; // INCORRECTO
    function Procesar_Archivo(Nombre_Archivo) { /* ... */ } // INCORRECTO
    class administrador_tareas { /* ... */ } // INCORRECTO
    interface opciones_config { /* ... */ } // INCORRECTO
    type idusuario = string | number; // INCORRECTO
    enum nivelAcceso { lector, editor, admin } // INCORRECTO

Cuándo Aplicar

Siempre.

Cuándo Evitar o Flexibilizar

Nunca. Si existen linters/formatters (ESLint/Prettier), seguirlos si extienden estas reglas.

2. Reglas de Declaración de Variables

Regla Principal

Regla: Usar const por defecto. Usar let solo si se requiere reasignación. Prohibido var.

Contexto y Justificación

const fomenta inmutabilidad. let tiene ámbito de bloque claro. var causa problemas de hoisting y ámbito.

Ejemplos y Contraejemplos

  • Correcto:
    const API_KEY = 'abc';
    const settings = { theme: 'dark' };
    let counter = 0;
    counter++;
  • Incorrecto:
    let apiKey = 'abc'; // INCORRECTO si no se reasigna
    const count = 0;
    // count++; // INCORRECTO: TypeError
    var oldVar = 'No usar'; // INCORRECTO

Cuándo Aplicar

Siempre.

Cuándo Evitar o Flexibilizar

Nunca para var. Decisión const/let basada estrictamente en reasignación.

3. Reglas de Estructuras de Control y Flujo

Regla Principal

Regla:

  1. Retornos Tempranos (Early Returns): Favorecer retornos tempranos para evitar anidación excesiva en if.
  2. Uso de switch: Usar switch para evaluar una expresión contra múltiples constantes, en lugar de if-else if-else.

Contexto y Justificación

Retornos tempranos mejoran legibilidad. switch es más semántico y eficiente para comparaciones discretas.

Ejemplos y Contraejemplos

Retornos Tempranos:

  • Correcto:
    function procesar(data) {
    if (!data) { return; /* Temprano */ }
    if (!data.activo) { return; /* Temprano */ }
    console.log('Procesando...');
    }
  • Incorrecto:
    function procesar(data) {
    if (data) { // Anidado
    if (data.activo) { // Anidado
    console.log('Procesando...');
    }
    }
    }

Uso de switch:

  • Correcto:
    function getMensaje(estado) {
    switch (estado) {
    case 'A': return 'Estado A';
    case 'B': return 'Estado B';
    default: return 'Desconocido';
    }
    }
  • Incorrecto:
    function getMensaje(estado) {
    if (estado === 'A') { return 'Estado A'; }
    else if (estado === 'B') { return 'Estado B'; }
    else { return 'Desconocido'; }
    }

Cuándo Aplicar

Retornos tempranos siempre. switch para comparaciones con múltiples constantes.

Cuándo Evitar o Flexibilizar

switch: Si las condiciones son complejas (rangos, etc.), usar if-else if.

4. Reglas sobre Funciones Puras y Arrow Functions

Regla Principal

Regla:

  1. Funciones Puras: Priorizar funciones puras (sin efectos secundarios, mismo resultado para mismos args).
  2. Arrow Functions: Usar => para funciones anónimas, callbacks y métodos de clase que necesiten this léxico. Usar function para funciones nombradas de nivel superior o métodos que no dependan de this léxico si mejora legibilidad.

Contexto y Justificación

Puras: predecibles, testeables. Arrow: sintaxis concisa, resuelve problemas de this.

Ejemplos y Contraejemplos

Funciones Puras:

  • Correcto:
    function sumar(a: number, b: number): number { return a + b; }
    function filtrarPares(nums: number[]): number[] { return nums.filter(n => n % 2 === 0); }
  • Incorrecto (Impura):
    let total = 0;
    function sumarAGlobal(val: number): void { total += val; } // Efecto secundario
    function guardar(data: object): void { console.log(data); } // Efecto secundario (I/O)

Arrow Functions:

  • Correcto:
    const duplicados = [1, 2].map(n => n * 2);
    class Timer {
    tiempo = 10;
    iniciar() {
    setInterval(() => { this.tiempo--; }, 1000); // 'this' correcto
    }
    }
  • Incorrecto:
    const triplicados = [1, 2].map(function(n) { return n * 3; }); // INCORRECTO: Verboso
    class Handler {
    mensaje = 'Click!';
    attach(btn) {
    // INCORRECTO: 'this' se pierde con function()
    btn.addEventListener('click', function() { console.log(this.mensaje); });
    }
    }

Cuándo Aplicar

Puras: lógica de negocio, transformaciones. Arrow: callbacks, anónimas, métodos con this.

Cuándo Evitar o Flexibilizar

Puras: No aplicable a I/O o mutación necesaria. Arrow: No usar si se necesita this dinámico (raro), no usar para constructores, usar function* para generadores.

5. Reglas de Manejo de this y Ámbitos

Regla Principal

Regla:

  1. Evitar this fuera de Clases: Evitar this en funciones que no sean métodos de clase/constructores.
  2. Preservar Contexto con Arrow Functions: En clases, usar arrow functions para métodos usados como callbacks para asegurar que this se refiera a la instancia.

Contexto y Justificación

this es fuente de errores. Limitarlo a clases y usar arrow functions para fijar contexto mejora predictibilidad.

Ejemplos y Contraejemplos

  • Correcto:
    class Controlador {
    datos = ['a'];
    constructor(nodo) {
    nodo.addEventListener('click', this.handleClick); // 'this' correcto aquí
    }
    handleClick = (e: Event): void => { // Arrow function captura 'this'
    console.log(this.datos); // 'this' es la instancia
    }
    }
  • Incorrecto:
    function mostrarPropGlobal() {
    console.log(this.prop); // INCORRECTO: 'this' impredecible
    }
    class OtroControlador {
    datos = ['b'];
    constructor(nodo) {
    // INCORRECTO: 'this' se pierde en manejarClick
    nodo.addEventListener('click', this.manejarClick);
    }
    manejarClick(e: Event): void { // Método con 'function'
    console.log(this.datos); // INCORRECTO: 'this' no es la instancia
    }
    }

Cuándo Aplicar

Siempre que se use this o se pasen métodos como callbacks.

Cuándo Evitar o Flexibilizar

No flexibilizar. Evitar this fuera de clases.