Historia del tema:
Las propiedades y métodos estáticos aparecieron en las clases de JavaScript a partir de ES6, sin embargo, el tipado estricto de estos elementos se hizo posible gracias a TypeScript. En el JavaScript dinámico, los elementos estáticos de la clase no se diferencian en tipo de los no estáticos, pero TypeScript permite añadir seguridad de tipos y estructura de clases considerando los miembros estáticos.
Problema:
Las propiedades y métodos estáticos pertenecen a la propia clase, no a sus instancias. Sin embargo, muchos desarrolladores confunden el tipado de la instancia (a través de this o el constructor) y el tipado de la propia clase como objeto. Esto a veces conduce a errores al acceder a los campos estáticos dentro de los métodos o al heredar.
Solución:
En TypeScript, los miembros estáticos de las clases se tipan por separado de los no estáticos:
Ejemplo de código:
class User { static count: number = 0; name: string; constructor(name: string) { this.name = name; User.count++; } static getCount(): number { return User.count; } } function createUserClass(): typeof User { return User; }
Características clave:
¿Pueden los métodos estáticos trabajar con propiedades no estáticas de la clase directamente?
No, los métodos estáticos no tienen acceso a las propiedades no estáticas a través de this, ya que this apunta a la propia clase (constructor). Para trabajar con propiedades no estáticas, es necesario trabajar con las instancias del objeto.
class Demo { static demoStatic() { // this.value; // Error — value no es static } }
¿Se puede acceder a una propiedad estática a través de una instancia de la clase?
No, el acceso a las propiedades estáticas solo es posible a través del propio nombre de la clase, no a través de una instancia:
const u = new User('Max'); console.log(u.count); // Error console.log(User.count); // OK
¿Se pueden heredar y redefinir los métodos estáticos al heredar la clase?
Sí, los métodos estáticos pueden ser heredados y redefinidos, y funcionará como se espera:
class Animal { static who() { return 'Animal'; } } class Dog extends Animal { static who() { return 'Dog'; } } console.log(Dog.who()); // 'Dog'
Un desarrollador guarda el contador de instancias creadas como una propiedad de instancia normal, y no como estática. Al crear cada objeto, el campo se incrementa, pero no está sincronizado para todos los objetos de la clase.
Ventajas:
Desventajas:
Uso de static count para contabilizar todos los objetos, aumento correcto en el constructor y método estático para obtener el contador.
Ventajas:
Desventajas: