在TypeScript中执行继承时出错

时间:2019-02-23 17:48:33

标签: 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", "iro@gmail.com", 4556);

console.log(newUser.checkUserData());

这是我的代码,在这里我得到以下错误

  

index.ts:31:11-错误TS2340:仅公共和受保护的方法   可以通过'super'关键字访问基类。

     

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

     

index.ts:37:13-错误TS2554:预期有1个参数,但有0个。

     

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

     

index.ts:10:19       10 checkUserData = id => {                            ~~       未提供“ id”的参数

在我的代码中,没有看到使用private method的原因,为什么会出现该错误?另外,我知道我的代码中有太多错误,有人可以帮我修复它吗?

我的意图是什么?

继承类用户, 在以ID为参数的父类(将其视为通用类)中创建新属性checkUserData, 从其子级中调用该类并向其传递ID。

1 个答案:

答案 0 :(得分:1)

这感觉像两个独立的问题,但我将在此处回答它们:


这是我更改您的代码的方式:

// 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", "iro@gmail.com", 4556);

console.log(newUser.checkUserData());

注意:按照惯例,非基本类型以大写字母开头,因此我将user更改为User,并将college更改为College。拥有小写的类名不是无效,但它违反了预期。如果需要,可以随意将它们小写。


问题一:“为什么我不能打super?”

答案一:您正在使用函数属性而不是方法。改用方法。

详细信息:我已将checkUserData()User中的College更改为prototype method。这意味着它们被添加到User.prototypeCollege.prototype中,而UserCollege的实例只是通过prototypical inheritance继承它们。现在,您可以在this中使用College.prototype.checkUserData()super。将方法定义为arrow functions的方式是不可能的。箭头函数没有自己的thissuper上下文,并且UserCollege的每个实例都将获得其箭头函数的own副本,因此您无法通过原型继承来覆盖它。箭头函数(如MDN docs中所述)不适合用作方法。


问题二:“ newUser.checkUserData()为什么给我一个错误?

答案二:您已声明newUser的类型为User。使其不加注释,或将其声明为College类型。

详细信息:当您说let newUser: User = ...时,是在告诉编译器它是User,并且编译器不会尝试找出它是否是更具体的类型,例如College。 ,即使您知道它是一个。由于User实例需要其checkUserData()方法采用单个参数,因此会出现错误。解决此问题的方法是让编译器知道newUser实际上是College。您可以通过对其进行注释(let newUser: College = ...来明确地执行此操作,也可以通过查看{的返回类型,而忽略注释,并让编译器infer属于College实例。 {1}}。


好的,希望能有所帮助。祝你好运!