es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Typescript: Acortando la Declaración de Clases Simples

Tengo un patrón de código en TS que encuentro muy útil pero es extremadamente no DRY. ¿Alguna idea de cómo solucionarlo?

Me gusta “vincular” una interface de TS con una declaración de class. De esta manera tengo la ventaja de tener una estructura de datos simple con tipado y herencia, Y puedo realizar fácilmente comprobaciones de tipo en tiempo de ejecución con el operador instanceof (que me permite evitar los predicados de tipo, que considero inseguros).

Para ver un ejemplo, consulta el siguiente código donde tengo una clase Doctor que extiende una clase base Person

interface PersonInterface {
  id: number
  name: string
  surname: string
}
class Person implements PersonInterface {
  id: number
  name: string
  surname: string

  constructor(arg: PersonInterface) {
    this.id = arg.id
    this.name = arg.name
    this.surname = arg.surname
  }
}

interface DoctorInterface extends PersonInterface {
  degree: string
  salary: number
}
class Doctor extends Person implements DoctorInterface {
  degree: string
  salary: number

  constructor(arg: DoctorInterface) {
    super(arg)
    this.degree = arg.degree
    this.salary = arg.salary
  }
}

const doc = new Doctor({
  id: 111,
  name: 'John',
  surname: 'Johnson',
  degree: 'PHD',
  salary: 100000,
})

console.log(doc instanceof Person) // true
console.log(doc instanceof Doctor) // true

Todo funciona, la comprobación de tipos es fácil y mi IntelliSense está contento. Todo genial. Pero como puedes ver, estoy repitiendo el código 3 veces para cada clase. Una vez para declarar la interface, otra vez para implementarla en la class y una final para aplicar el constructor.

¿No hay una forma más concisa? En un proyecto grande esto se vuelve horrible de ver.

IMPORTANTE
No necesito tener métodos en mis clases. Solo se utilizan para representar datos, no comportamiento (de hecho los estoy utilizando para poblar una tienda vuex).

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Sí, hay una forma más concisa de lograr el mismo resultado sin repetirse varias veces. Puede utilizar la sintaxis de class de TypeScript en combinación con interface para definir un patrón de código más simple y limpio.

    Aquí tienes un ejemplo:

    interface PersonInterface {
      id: number
      name: string
      surname: string
    }
    
    class Person implements PersonInterface {
      constructor(public id: number, public name: string, public surname: string) {}
    }
    
    interface DoctorInterface extends PersonInterface {
      degree: string
      salary: number
    }
    
    class Doctor extends Person implements DoctorInterface {
      constructor(public degree: string, public salary: number, person: PersonInterface) {
        super(person.id, person.name, person.surname)
      }
    }
    
    const doc = new Doctor("PHD", 100000, new Person(111, "John", "Johnson"))
    
    console.log(doc instanceof Person) // true
    console.log(doc instanceof Doctor) // true
    

    En este ejemplo, estamos utilizando el modificador public de TypeScript en los parámetros del constructor, lo cual define automáticamente las propiedades de la clase. También podemos pasar el PersonInterface como parámetro al constructor de Doctor y usarlo para llamar al constructor super en Person.

    Al hacer esto, logramos la misma estructura de datos y verificación de tipos sin repetirnos con la declaración de interface, class e implementación de constructor.

    Este enfoque cumple con el principio DRY y es más fácil de leer y mantener.

Comments are closed.