0

I have been trying to comprehend inheritance in typescript

class user {
  name: string;
  email: string;

  constructor(name: string, email: string) {
    this.name = name;
    this.email = email;
  }

  checkUserData = id => {
    console.log(
      "This user name is" +
        this.name +
        "his email address is" +
        this.email +
        "and his ID is" +
        id
    );
  };
}

class college extends user {
  id: number;

  constructor(name, email, id) {
    super(name, email);
    this.id = id;
  }

  checkUserData = () => {
    super.checkUserData(this.id);
  };
}

let newUser: user = new college("Rohit Bhatia", "[email protected]", 4556);

console.log(newUser.checkUserData());

This is my code, Here I am getting following error

index.ts:31:11 - error TS2340: Only public and protected methods of the base class are accessible via the 'super' keyword.

31 super.checkUserData(this.id); ~~~~~~~~~~~~~

index.ts:37:13 - error TS2554: Expected 1 arguments, but got 0.

37 console.log(newUser.checkUserData()); ~~~~~~~~~~~~~~~~~~~~~~~

index.ts:10:19 10 checkUserData = id => { ~~ An argument for 'id' was not provide

In my code, I don't see use of private method so why am I getting that error? Also, I know there is so much wrong in my code, Can someone help me fixing it?

What are my intentions?

Inherting class user, creating a new property checkUserData in parent class (considering this as a common class) which takes ID as a parameter, Calling that class from one its child and passing id to it.

5
  • You are making checkUserData a function-valued property instead of a method. They are different. Try checkUserData(id: number) { /* impl */ } instead of checkUserData = id => { /* impl */ }. Commented Feb 23, 2019 at 18:02
  • Also for your second question, don't annotate newUser as user and then try to call its checkUserData() method with no argument, because user.checkUserData() takes an argument. You need to annotate it as let newUser: college or just let newUser = new college(...). Once you widen newUser from college to user, the compiler has no idea that it is a college anymore and won't let you call college-specific methods. Commented Feb 23, 2019 at 18:03
  • 1
    And usually SO works best with just one subject per question... "help me fix all these issues" is helpful to the asker but not much help to people coming later. So if you have multiple issues you should probably open multiple questions. Commented Feb 23, 2019 at 18:04
  • 1
    If any of these comments helps I might flesh them out into an answer when I get to a real computer (otherwise I won't be offended if someone else decides to make a real answer before me) Commented Feb 23, 2019 at 18:05
  • I partially got what you said, can you explain it in details what you are trying to convery? Commented Feb 23, 2019 at 20:33

1 Answer 1

2

This feels like two separate questions, but I will answer them both here:


Here's how I'd alter your code:

// non-primitive types should start with a capital letter by convention
class User {
  name: string;
  email: string;

  constructor(name: string, email: string) {
    this.name = name;
    this.email = email;
  }

  // a method on the prototype, not an instance property
  checkUserData(id: number) {
    console.log(
      "This user name is" +
      this.name +
      "his email address is" +
      this.email +
      "and his ID is" +
      id
    );
  };
}


// non-primitive types should start with a capital letter by convention
class College extends User {
  id: number;

  // annotate types on function parameters
  constructor(name: string, email: string, id: number) {
    super(name, email);
    this.id = id;
  }

  // a method on the prototype, not function property
  checkUserData() {
    super.checkUserData(this.id);
  };
}

// do not widen to user type, let the compiler infer as college
let newUser = new College("Rohit Bhatia", "[email protected]", 4556);

console.log(newUser.checkUserData());

Note: By convention, non-primitive types start with an uppercase letter, so I've changed user to User and college to College. It's not invalid to have lowercase class names, but it violates expectations. Feel free to leave them lowercase if you want.


Question One: "why can't I call super?"

Answer One: you are using function properties instead of methods. Use methods instead.

Detail: I have changed checkUserData() in both User and College to be a prototype method. That means that they are added to User.prototype and College.prototype, and instances of User and College just inherit them via prototypical inheritance. Now you can use this and super inside College.prototype.checkUserData(). The way you defined the methods, as arrow functions, this wasn't possible. An arrow function does not have its own this or super context, and each instance of User and College would get its own copy of the arrow function, so you couldn't override it via prototypical inheritance. Arrow functions are (as it says in the MDN docs) ill-suited as methods.


Question Two: "why does newUser.checkUserData() give me an error?"

Answer Two: you have declared that newUser is of type User. Leave it unannotated, or declare it as type College instead.

Detail: When you say let newUser: User = ... you are telling the compiler that it is a User, and the compiler will not try to figure out if it is a more specific type like College, even though you know it is one. Since a User instance requires its checkUserData() method to take a single argument, you will get an error. The way to fix this is to let the compiler know that newUser is actually a College. You can do this explicitly by annotating it (let newUser: College = ...), or you can just leave out the annotation and let the compiler infer that it's a College instance by looking at the return type of new College(...).


Okay, hope that helps. Good luck!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.