- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
如果我通过子类实例调用基类的 update
方法,它可以工作,但如果我在子类方法中执行它,它会给我这个错误:
Argument of type '{ prop: number; }' is not assignable to parameter of type 'Partial<this>'.
class Base {
update(modifier: Partial<this>) {
Object.keys(modifier).forEach(key => {
this[key] = modifier[key];
});
}
}
class Sub extends Base {
prop;
job() {
// Error: Argument of type '{ prop: number; }' is not assignable
// to parameter of type 'Partial<this>'.ts(2345)
this.update({ prop: 1 });
}
}
new Sub().update({ prop: 1 }); // but it works here!
Live on the TypeScript playground .
我该如何解决?
最佳答案
多态 this
不是常规类型,它实际上是您的类的类型参数。由编译器管理的隐藏类型参数,但仍然是类型参数。自 this
只是一个类型参数,具有扩展当前类的约束(类似于 class Base<This extends Base> {}
)它在类内部并不完全为人所知。
SO 上有很多关于为什么我们不能为泛型类型参数的变量赋值,或者为什么条件/映射类型不能很好地与泛型类型参数一起工作的问题。例如,这也不起作用:
function partial<T extends { prop: number }>(): Partial<T> {
return { prop: 1 }
}
这类一般问题不起作用的原因是我们只知道最小接口(interface) T
必须实现,我们不知道T
完全。考虑这个例子:
function getObj<T extends { prop: { name: string } }>(): Partial<T> {
return { prop: { name: "" } }// still an error
}
var r = getObj<{ prop: { name: string, lastName: string}}>();
r.prop!.lastName // r should have last name, where is my lastName ?!
prop
在 T
被限制为 name
,但它可以有更多的 Prop ,如下面的有效调用所示。我们期望 r
尊重T
传入但实际上返回的值对于给定的 T
无效.为了防止这种意外,typescript 通常不允许我们在涉及类型参数的地方分配具体值(因为我们并不真正知道类型参数的最终形状)
回到多态 this
,上述推理成立,this
是一个不完全已知的类型参数,因此无法将对象字面量分配给它,因为我们不知道 this
的最终形状.
考虑一个与上面类似的例子:
class Base {
update(modifier: Partial<this>) {
Object.keys(modifier).forEach(key => {
this[key] = modifier[key];
});
}
}
class Sub extends Base {
prop! :{
name: string
};
job() {
this.update({ prop: { name: string } }); // not valid for any class, example below
}
}
class Sub2 extends Sub {
prop! : {
name: string
lastName: string
};
}
我选择替换number
使用对象类型,因为它更容易理解问题,但是 number
可能会出现类似的类型问题.数字可以是派生类中的数字文字类型。
类外多态this
是已知的(就像在调用通用函数时已知的一样)这就是调用在类外成功的原因。
new Sub().update({ prop: 1 }); // this is Sub for this call so Partial<Sub> is { prop?: number }
类内部多态this
可能是 Sub
或 Sub
的任何派生类.外面this
折叠为仅调用函数的特定类型引用(这也不是 100% 的声音,但这是使它有用的折衷)
解决此问题的唯一方法是使用类型断言并接受这不是类型安全的。或者使用表示类属性的第二个类型参数,尽管这将意味着您的继承层次结构只能有一个可以添加新属性的级别。
class Base<TProps> {
update(modifier: Partial<TProps>) {
Object.assign(this, modifier);
}
}
class Sub extends Base<Sub> {
prop: number;
job() {
this.update({ prop: 1 });
}
}
关于typescript - 如何在子类方法中修复 'cannot assign to Partial<this>'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56456641/
我是一名优秀的程序员,十分优秀!