skip to Main Content

what’s the best way to solve this issue?
I love the way that we can define attributes in the constructor and TS does all the magic for us to resolve the resp. lines of code in order to assign the values to the props in JavaScript – what I did here with department.

But I’ curious if there is something useful for inheritanceas well.
Is there a way to let’s say init a subclass with all attributes and pass them along to the super call without repeating all the properties here?

I would not like to manually put there /* all the other attributes of the base class*/ in order to init the class and satisfy the super call.

Thanks in advance and regards.

class Manager extends Employee {
  constructor(public department: number, /* all the other attributes of the base class*/ ){
    super( /* all the other attributes of the base class*/ );
  }
}

let myEmp = new Employee(1, "James"); // Base class
let myMng = new Manager (101, 2, "Jane" ); // Subclass

After some of your helpful feedback, I ended up here. Gonna try to tweak it a bit to get rid of explicitly naming and listing the superclass members in the super-call.
It would be nice and helpful to hear some thoughts on this approach.

class Manager extends Employee {
  constructor(public department: number, empData: Employee) {
    super(empData.id, empData.name);
  }
}

2

Answers


  1. Instead of positional arguments to the constructors, use an object with named properties. Since the "options" object will be a super type of the type of the options object for the base class you can just pass the whole thing:

    interface FooArgs {
      a: number
      b: string
    }
    
    class Foo {
      public a: number;
      public b: string;
    
      constructor(args: FooArgs) {
        this.a = args.a;
        this.b = args.b;
      }
    }
    
    interface BarArgs extends FooArgs {
      c: number
    }
    
    class Bar extends Foo {
      public c: number;
      
      constructor(args: BarArgs) {
        super(args);
        this.c = args.c;
      }
    }
    

    Playground

    This also has the added benefit of making your args more human-readable at the call site where you new up these objects:

    const John = new Employee({ age: 32, salary: 60000, name: 'John Smith' });
    const Mary = new Manager({ age: 45, salary: 90000, name: 'Mary Brown', directReports: 7 });
    
    Login or Signup to reply.
  2. You can leverage parameter object pattern here. Instead of passing many parameters by one pass single parameter wuth multiple fields.

      type EmployeeParams = {
        // superclass params
      }
    
      type ManagerParams = {
        department: number
      } & EmployeeParams;
    
      class Employee {
        // declare all the fields
        constructor(params: EmployeeParams){
          // assign all the fields
        }
      }
    
      class Manager extends Employee {
        department: number;
        constructor(params: ManagerParams){
          super(params);
          this.department = params.department;
        }
      }
    

    Note that you need now explicitly declare separate fields on the class.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search