gpt4 book ai didi

typescript - 如何在子类方法中修复 'cannot assign to Partial'?

转载 作者:搜寻专家 更新时间:2023-10-30 21:09:37 26 4
gpt4 key购买 nike

如果我通过子类实例调用基类的 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 ?!

propT被限制为 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可能是 SubSub 的任何派生类.外面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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com