必须在子类Class方法中使用TS 2.4指定扩展类类型

时间:2018-01-26 13:48:17

标签: typescript migration parent-child typescript2.4

我正在尝试从TypeScript 2.3.2迁移到2.4.2。

此代码曾用于2.3:

class Records {
  public save(): Records {
    return this;
  }
}

class User extends Records {
  public update(): User {
    return this.save();
  }
}

let myUser: User = new User();
let obj = myUser.update();

但是现在,它在编译时引发了以下错误:

  

错误:(10,5)TS2322:类型“记录”不能分配给“用户”类型。    “记录”类型中缺少“更新”属性。

当然,我可以更改更新,以便返回“记录”,如下所示:

  public update(): Records {
    return this.save();
  }

但我真的不明白为什么我要改变它。对我来说这看起来像是回归。 有人有解释或更好的解决方案吗?我发现它使我的代码更难阅读。

非常感谢,

于连

3 个答案:

答案 0 :(得分:1)

这是打字问题。您说User.update将返回User,但实际上会返回Records.save的结果,其类型为Records。无法将Records类型分配给期望User的内容,因为Records没有update方法。

要解决此问题,您必须将update的返回类型指定为Records(当前正在返回),或者您需要修改Records.save以返回{ {1}}(这将需要更改方法的实现) - 您的解决方案将取决于您的程序需要。

我认为您的部分混淆可能来自User关键字 - 看似extends UserRecords有点相同,因为User&#34 ; extends" Records,但事实并非如此。在"继承"中阅读有关extends的更多信息。本文的一部分:https://www.typescriptlang.org/docs/handbook/classes.html

在回复您的评论时(假设您无法更改实施方式),save方法的更准确类型将是User | Records的联合类型,因为它将返回一个或另一个取决于它被调用的上下文。

看起来像这样:

public save(): Records | User {
  return this;
}

在此处阅读联盟类型:https://www.typescriptlang.org/docs/handbook/advanced-types.html

答案 1 :(得分:0)

在OOP中,基类不知道派生类的新方法和新属性是什么,这就是编译器抱怨你的原因。

如何回归'这个'?你有可能吗?

class User extends Records {
   public update(): User {
      super.save();
      return this;
   }
}

答案 2 :(得分:0)

解决您问题的理想方法是仅删除save()方法的返回类型。

Check it live(不再有错误)

说明:方法变为后:

public save() { // With no explicit return type.
    return this;
}

这意味着打字稿的“类型推断”功能将推断类型为Records或类型为Records的任何子类。