
Cuando se colabora en un proyecto de software, uno de los mayores desafíos es lograr que todos los miembros del equipo puedan comprender, extender y depurar el código con facilidad. Un factor clave para alcanzar este objetivo es establecer una metodología clara para nombrar los elementos del código (como clases, interfaces, funciones o variables), así como definir el orden en que deben aparecer sus componentes (por ejemplo, propiedades, métodos públicos y privados).
Aunque estas decisiones pueden parecer triviales al principio, su impacto se vuelve evidente a medida que el proyecto crece en tamaño y complejidad. La falta de una metodología clara puede dificultar la incorporación de nuevos desarrolladores y hacer más costoso el mantenimiento del código. La coexistencia de múltiples estilos y la falta de consistencia generan fricción: cuesta más entender qué hace una función, el código se vuelve más difícil de revisar y se pierden minutos valiosos en discusiones subjetivas sobre estilo, en lugar de centrarse en la funcionalidad o la arquitectura.
En esta entrada explicaré cómo voy a introducir estas convenciones en tslane, una plantilla para la creación de librerías en TypeScript desarrollada en una serie anterior. Servirá como ejemplo para quienes buscan estandarizar estas prácticas dentro de sus propios proyectos. En concreto, abordaré:
- Por qué es importante definir una convención de nombres y un orden lógico para los miembros del código.
- Qué ventajas concretas aporta esta metodología al trabajo colaborativo y al mantenimiento del código.
- Cómo se puede automatizar su cumplimiento mediante ESLint y el plugin
@typescript-eslint
.
Al finalizar esta lectura, comprenderás no solo cómo, sino también el por qué de definir y aplicar una metodología de estilo clara en TypeScript (o en otros lenguajes). Si participas en equipos de desarrollo, revisas código con frecuencia o mantienes librerías reutilizables, aplicar estas buenas prácticas puede marcar una gran diferencia.

Tabla de contenidos
Ventajas de una metodología clara
Antes de comenzar, veamos cuáles son las ventajas de contar con una metodología clara y bien definida, tanto en la elección de nombres como en el orden de los métodos y miembros de las clases.
Definir convenciones de nombres
Establecer cómo deben nombrarse los distintos elementos del código no es una cuestión meramente estética: es una herramienta clave para mejorar la comprensión del sistema.
- Comunicación clara de la intención: Un nombre como
IUserRepository
deja claro que se trata de una interfaz, mientras que nombres comouser
ou
resultan mucho menos informativos. - Facilita la búsqueda y navegación: Seguir una convención consistente permite aprovechar mejor herramientas de autocompletado, búsqueda de texto o refactorización automática.
- Reduce errores semánticos: Al evitar nombres ambiguos o inconsistentes, se reduce la probabilidad de malentendidos durante el desarrollo o el mantenimiento.
Ordenar los miembros de las clases
Además de los nombres, el orden en el que se presentan las propiedades y métodos dentro de una clase (o incluso en un archivo) también influye directamente en la legibilidad del código.
- Mejor lectura secuencial: Un lector nuevo del archivo puede comenzar entendiendo las propiedades públicas, seguir con las privadas y, por último, revisar los métodos auxiliares o estáticos.
- Estilo de lectura predecible: Cuando todo el equipo sigue el mismo patrón, se reduce el tiempo necesario para comprender un nuevo archivo.
- Detección temprana de errores: Tener los métodos organizados permite identificar con mayor facilidad incoherencias, repeticiones o responsabilidades mal asignadas.
Reglas propuestas para ESLint
Para garantizar que estas convenciones se sigan de forma sistemática, podemos configurar reglas específicas en el archivo de ESLint. A continuación, se detallan las principales reglas que implementaremos y el motivo de cada una.
Convenciones de nombres con la regla @typescript-eslint/naming-convention
Esta regla permite definir cómo deben nombrarse los distintos tipos de identificadores. Algunas convenciones recomendadas son:
- Interfaces: deben comenzar con
I
seguido de PascalCase (IUser
,IProductRepository
). Esto permite distinguirlas rápidamente de clases y tipos. - Clases, tipos y enums: en PascalCase (
UserController
,HttpStatusCode
). Esta es una convención común en TypeScript y en el JavaScript moderno. - Variables: deben usar camelCase, excepto si son constantes globales, en cuyo caso pueden emplear UPPER_CASE.
- Propiedades privadas: deben llevar un prefijo
_
para distinguirlas visualmente (_internalId
).
Establecer estas convenciones ayuda a comunicar de inmediato la naturaleza de cada entidad en el código y mejora la coherencia en todo el proyecto.
Ordenar los miembros de las clases con la regla @typescript-eslint/member-ordering
Esta regla permite definir el orden en el que deben aparecer los miembros dentro de una clase. Por ejemplo, se recomienda el siguiente patrón:
- Firmas estáticas públicas
- Propiedades públicas
- Métodos públicos
- Propiedades privadas
- Métodos privados
Este orden mejora notablemente la legibilidad, ya que todas las clases siguen una estructura uniforme, facilitando la navegación y el mantenimiento del código.
Archivo de configuración de ESLint para TypeScript
Para implementar las reglas descritas anteriormente, utilizaremos un archivo de configuración llamado eslint.config.js
, ubicado en la raíz del proyecto. Este archivo configura ESLint para que funcione correctamente con TypeScript a través del plugin oficial @typescript-eslint
, e incluye reglas específicas tanto para las convenciones de nombres como para el orden de los miembros dentro de las clases.
A continuación, se muestra el archivo de configuración que se incluye en la versión 1.5.0 de plantilla tslane:
import eslintPluginTs from '@typescript-eslint/eslint-plugin'; import parser from '@typescript-eslint/parser'; export default [ { // Ignore folders and files that should not be linted by ESLint. // This improves performance and avoids false positives. ignores: [ 'node_modules/**', // External dependencies (not modified or linted). 'dist/**', // Compiled output (not source code). 'bundle/**', // Browser bundles (not source code). 'coverage/**', // Test coverage reports (generated files). 'webpack.config.js' // Webpack config file, usually not linted. ], }, { // Apply these rules only to source and test files in JS and TS. files: ['src/**/*.{js,ts,jsx,tsx}', 'test/**/*.{js,ts,jsx,tsx}'], languageOptions: { // Parser so ESLint can understand TypeScript parser, parserOptions: { ecmaVersion: 'latest', // Latest ECMAScript version for modern syntax. sourceType: 'module', // Use ES modules (import/export). project: './tsconfig.json', // Reference TS config for accurate analysis. }, }, plugins: { // Official plugin with TypeScript-specific rules. '@typescript-eslint': eslintPluginTs, }, rules: { // Import recommended rules from the TypeScript plugin ...eslintPluginTs.configs.recommended.rules, // Custom rules for naming conventions '@typescript-eslint/naming-convention': [ 'error', // Interfaces must be PascalCase and start with "I" followed by uppercase letter. { selector: 'interface', format: ['PascalCase'], custom: { regex: '^I[A-Z]', match: true }, }, // Classes use PascalCase { selector: 'class', format: ['PascalCase'] }, // Type aliases in PascalCase { selector: 'typeAlias', format: ['PascalCase'] }, // Enums in PascalCase { selector: 'enum', format: ['PascalCase'] }, // Variables in camelCase or UPPER_CASE, allow leading underscore for private vars { selector: 'variable', format: ['camelCase', 'UPPER_CASE'], leadingUnderscore: 'allow', }, // Functions in camelCase { selector: 'function', format: ['camelCase'] }, // Class methods in camelCase { selector: 'classMethod', format: ['camelCase'] }, ], // Member ordering in classes based on community best practices and Angular style guide // Groups static members, decorated members, fields, accessors, constructors, and methods '@typescript-eslint/member-ordering': ['warn', { default: [ 'signature', // Call signatures (overloads) // Static fields ordered by visibility 'public-static-field', 'protected-static-field', 'private-static-field', // Instance fields, decorated ones first to highlight importance 'public-decorated-field', 'public-instance-field', 'protected-decorated-field', 'protected-instance-field', 'private-decorated-field', 'private-instance-field', // Accessors (get/set) ordered by visibility 'public-get', 'public-set', 'protected-get', 'protected-set', 'private-get', 'private-set', // Constructors ordered by visibility 'public-constructor', 'protected-constructor', 'private-constructor', // Static methods ordered by visibility 'public-static-method', 'protected-static-method', 'private-static-method', // Instance methods, considering abstract and decorated methods 'public-abstract-method', 'public-decorated-method', 'public-instance-method', 'protected-abstract-method', 'protected-decorated-method', 'protected-instance-method', 'private-decorated-method', 'private-instance-method', ] }], }, } ];
Esta configuración permite asegurar que todas las partes del código TypeScript cumplan con un estilo coherente, fácil de mantener y comprensible para todos los miembros del equipo.
Ignorar carpetas innecesarias
La sección ignores
permite excluir rutas específicas del análisis de ESLint. Esto es fundamental para evitar revisar archivos que no forman parte del código fuente principal, lo que mejora el rendimiento del análisis y evita falsos positivos.
En esta configuración, se ignoran las siguientes carpetas y archivos:
node_modules
: Contiene las dependencias instaladas mediante npm. Estas bibliotecas externas no deben ser analizadas ni modificadas por ESLint.dist
: Carpeta generada automáticamente al compilar el código TypeScript. Como contiene archivos finales, no es necesario validarlos.bundle
: Almacena paquetes preparados para ser ejecutados en el navegador. Tampoco representa código fuente directo.coverage
: Incluye los informes generados por herramientas de cobertura de pruebas. No requiere análisis estático.webpack.config.js
’: Archivo de configuración de Webpack que normalmente no se analiza con ESLint, ya que no forma parte del código fuente principal y puede generar falsos positivos.
Ignorar estos directorios asegura que ESLint se enfoque exclusivamente en los archivos fuente y de prueba relevantes.
Configuración del parser y opciones del lenguaje
Para que ESLint pueda interpretar correctamente el código TypeScript, se configura el parser oficial: @typescript-eslint/parser
. Este parser extiende las capacidades de ESLint y permite analizar características propias del lenguaje como tipado estático, tipos genéricos, decoradores y otras sintaxis avanzadas.
En parserOptions
, se definen las siguientes opciones clave:
ecmaVersion: 'latest'
: Permite utilizar la sintaxis más reciente disponible en JavaScript.sourceType: 'module'
: Indica que se está utilizando el sistema de módulos ECMAScript.project: './tsconfig.json'
: Apunta al archivo de configuración de TypeScript, asegurando que ESLint respete las opciones específicas del proyecto, como paths, strict mode, o aliases.
Plugins y reglas específicas
Se emplea el plugin @typescript-eslint
, que extiende las funcionalidades estándar de ESLint con reglas diseñadas específicamente para el ecosistema TypeScript. Esto permite adoptar mejores prácticas y detectar errores que no serían identificables solo con las reglas de JavaScript.
Entre las reglas definidas, se destacan:
@typescript-eslint/naming-convention
Permite establecer convenciones uniformes para los nombres de interfaces, clases, tipos, variables y métodos. En nuestra configuración:
- Interfaces deben comenzar con
I
seguido de PascalCase (IUser
,IRepository
). - Clases, tipos y enums siguen el estilo PascalCase (
UserService
,HttpStatusCode
). - Variables utilizan camelCase o UPPER_CASE si son constantes.
- Métodos y funciones en camelCase.
- Variables privadas pueden llevar un guion bajo inicial (
_internalValue
).
Aplicar esta regla mejora la legibilidad del código y ayuda a identificar de forma rápida el propósito de cada entidad.
@typescript-eslint/member-ordering
Esta regla establece un orden predecible y detallado para los miembros dentro de una clase. Mantener un orden coherente contribuye a la uniformidad del código y facilita la navegación, especialmente en archivos con clases extensas.
En la configuración propuesta, los miembros se agrupan siguiendo este orden jerárquico:
- Firmas (signatures): Incluye métodos abstractos y sobrecargas de funciones.
- Campos estáticos (static fields): Ordenados por visibilidad — públicos, protegidos y privados.
- Campos de instancia (instance fields): Primero los decorados y luego los normales, también organizados por visibilidad (públicos, protegidos y privados).
- Accesores (getters y setters): Agrupados por visibilidad pública, protegida y privada.
- Constructores: Ordenados según su visibilidad.
- Métodos estáticos (static methods): Clasificados por visibilidad.
- Métodos de instancia (instance methods): Incluyendo métodos abstractos y decorados, organizados según su visibilidad.
Este orden permite distinguir claramente entre miembros estáticos e instanciados, resaltar los campos y métodos decorados (que suelen tener roles especiales como inyección de dependencias o validaciones), y priorizar las firmas y métodos abstractos para una mejor definición de contratos y herencias.
Mantener este orden estandarizado mejora la mantenibilidad del código y reduce el tiempo necesario para entender la estructura de una clase.
Instalación de ESLint y configuración de scripts npm
Antes de poder ejecutar ESLint en tu proyecto, debes asegurarte de que está instalado como dependencia de desarrollo. Si usas la plantilla de tslane, ESLint ya viene incluido desde la primera versión. En caso contrario, puedes instalarlo manualmente con el siguiente comando:
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin
eslint
: es el núcleo del linter, encargado de analizar el código.@typescript-eslint/parser
: permite a ESLint interpretar correctamente el código escrito en TypeScript.@typescript-eslint/eslint-plugin
: añade reglas específicas y mejores prácticas para proyectos TypeScript.
Configuración de un scripts npm en package.json
Para facilitar el uso de ESLint y asegurar que todos los miembros del equipo ejecuten el linter de manera uniforme, es recomendable definir un script en el archivo package.json
. Esto también garantiza que se utilice la versión local instalada del paquete y se respete la configuración específica del proyecto.
En tu archivo package.json
, añade o modifica la sección de scripts con lo siguiente:
"scripts": { "lint": "npx eslint" }
Con este script configurado, podrás ejecutar ESLint de forma sencilla mediante el comando:
npm run lint
Este comando ejecutará internamente npx eslint
, que analizará los archivos desde la raíz del proyecto, aplicando las reglas y exclusiones definidas en tu archivo de configuración eslint.config.js
.
Beneficios claros de esta metodología en equipos
Adoptar reglas estrictas de nomenclatura y ordenación con ESLint aporta numerosas ventajas, especialmente en entornos colaborativos y proyectos de largo plazo:
- Consistencia visual y estructural: Un código homogéneo facilita su lectura y comprensión, independientemente del autor. Esto ayuda a que todos los miembros del equipo trabajen con un mismo estándar, reduciendo confusiones.
- Reducción de errores: Al imponer nombres claros y un orden lógico en los miembros de las clases, se favorece la detección temprana de bugs, malas prácticas o inconsistencias.
- Mejor mantenimiento: Un código bien organizado y estandarizado facilita añadir, modificar o depurar funcionalidades, lo que ahorra tiempo y esfuerzo a largo plazo.
- Facilita la revisión de código: Los revisores pueden enfocarse en la lógica y funcionalidad del código sin distraerse en aspectos superficiales como estilo o convenciones de nomenclatura.
- Onboarding más rápido: Para los nuevos integrantes del equipo, contar con reglas claras acelera la comprensión de la estructura y estándares del proyecto, facilitando su incorporación.
- Automatización y escalabilidad: Herramientas como ESLint permiten aplicar y hacer cumplir estas reglas de manera automática, evitando revisiones manuales tediosas y asegurando la calidad constante a medida que el proyecto crece.
Implementar esta metodología no solo mejora la calidad del código, sino que también fortalece la colaboración y eficiencia del equipo, sentando bases sólidas para proyectos exitosos y sostenibles.
Conclusiones
En el desarrollo de software, los pequeños detalles marcan una gran diferencia. Aunque pueda parecer trivial, la forma en que nombramos y ordenamos los elementos de nuestro código impacta directamente en su mantenibilidad, legibilidad y coherencia a largo plazo. Cuando trabajamos en solitario, tal vez podamos depender de la memoria o del estilo personal. Pero en equipos, especialmente en proyectos que evolucionan con el tiempo, necesitamos reglas claras y automáticas que garanticen consistencia sin generar fricción.
Adoptar convenciones explícitas de nomenclatura y orden —y reforzarlas mediante herramientas como ESLint— no es una cuestión de pedantería, sino una inversión en salud técnica. Es asegurarse de que cada miembro del equipo pueda desplazarse por el código sin dificultades, entender estructuras a simple vista y detectar anomalías sin profundizar en detalles irrelevantes.
Además, automatizar estas reglas libera a los revisores de tareas mecánicas, permitiéndoles concentrarse en lo realmente importante: la lógica, el diseño, la seguridad y el rendimiento. Ya no es necesario debatir en cada pull request si se debería llamar startDate
o StartDate
, ni cuestionar el orden de las propiedades dentro de una clase. El sistema lo hace por nosotros, y lo hace de forma predecible.
En definitiva, nombrar y ordenar no es un acto menor: es una forma silenciosa de comunicar y colaborar. Escribir código es escribir para otros humanos tanto como para la máquina. Por ello, cuidar el lenguaje y su estructura es un signo de respeto y profesionalismo.
Nota: La imagen de este artículo fue generada utilizando un modelo de inteligencia artificial.
Deja una respuesta