我正在尝试从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();
}
但我真的不明白为什么我要改变它。对我来说这看起来像是回归。 有人有解释或更好的解决方案吗?我发现它使我的代码更难阅读。
非常感谢,
于连
答案 0 :(得分:1)
这是打字问题。您说User.update
将返回User
,但实际上会返回Records.save
的结果,其类型为Records
。无法将Records
类型分配给期望User
的内容,因为Records
没有update
方法。
要解决此问题,您必须将update
的返回类型指定为Records
(当前正在返回),或者您需要修改Records.save
以返回{ {1}}(这将需要更改方法的实现) - 您的解决方案将取决于您的程序需要。
我认为您的部分混淆可能来自User
关键字 - 看似extends
User
和Records
有点相同,因为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
的任何子类。