ProgramaciónDesarrollador Backend

¿Cómo funciona el mecanismo de tipado de propiedades y métodos estáticos en TypeScript, qué peculiaridades existen en la definición de sus tipos y en qué se diferencia del tipado de los elementos no estáticos de la clase?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

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:

  • Para los miembros no estáticos se utiliza la descripción a través del cuerpo de la clase.
  • Para los estáticos — a través de la palabra clave static.
  • El tipo de la propia clase se puede describir usando la construcción typeof, para transmitir y utilizarlo de manera segura como objeto con una estructura específica.

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:

  • Los miembros estáticos no residen en la instancia, sino en el constructor de la clase, por lo tanto, solo son accesibles a través de la propia clase
  • Para transmitir/tipar la propia clase se utiliza typeof User, y para instancias — User
  • Para los métodos estáticos existen sus propias limitaciones (sin acceso a this, si no se invoca a través del constructor de la clase)

Preguntas capciosas.

¿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'

Errores típicos y anti-patrones

  • Confusión entre miembros estáticos y no estáticos de la clase
  • Intento de acceder a campos estáticos a través de la instancia
  • Errores al utilizar this dentro de los métodos estáticos

Ejemplo de la vida real

Caso negativo

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:

  • Fácil de implementar sin conocimiento sobre static

Desventajas:

  • Violación de invariantes, el contador no refleja el número de objetos, posibilidad de errores al crear en masa

Caso positivo

Uso de static count para contabilizar todos los objetos, aumento correcto en el constructor y método estático para obtener el contador.

Ventajas:

  • Garantía de contabilización correcta, encapsulación de la lógica solo en la clase
  • Los campos estáticos no se pueden confundir con los campos de instancia

Desventajas:

  • Requiere comprensión de la diferencia entre static e instance, es necesario recordar la sintaxis