我无法弄清楚为什么下面的代码会导致错误。在这个简单的示例中,正如预期的那样,Component
类没有问题。但是,明确将State
定义为从BaseState
扩展的通用实现似乎并未通过BaseState
提供的输入信息发送,从而导致错误。
interface BaseState {
on: boolean;
color: string;
};
class Component {
state: BaseState;
constructor(state: BaseState) {
this.state = state;
}
setState(partialState: Partial<BaseState>) {
this.state = { ...this.state, ...partialState }; // no error
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // no error
}
}
class GenericComponent<State extends BaseState> {
state: State;
constructor(state: State) {
this.state = state;
}
setState(partialState: Partial<State>) {
this.state = { ...this.state, ...partialState }; // error: Spread types may only be created from object types.
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // error: Argument of type '{ on: boolean; }' is not assignable to parameter of type 'Partial<State>'
}
}
我在这里缺少什么?
答案 0 :(得分:1)
请注意,这不是上述问题的精确解决方案,而只是一种解决方法。但是,评论时间太长了。
关于第二个错误,即&#34;类型的参数&#39; {on:boolean; }&#39;不能分配给&#39; Partial&#39;&#34;类型的参数,社区中围绕此主题进行了一些讨论,例如: https://github.com/Microsoft/TypeScript/issues/12793,https://github.com/DefinitelyTyped/DefinitelyTyped/pull/13155,但我没有找到与您的方案完全匹配的内容。
出于某种原因,尽管事实Partial<State>
,TS确实无法推断Partial<BaseState>
与State extends BaseState
的可转让性。
例如,以下代码会导致错误。
class SampleClass<State extends BaseState> {
baseState: Partial<BaseState>;
method(state: Partial<State>): void {
this.baseState = state; // Type 'Partial<State>' is not assignable to type 'Partial<BaseState>'.
}
}
这对我来说很奇怪,我建议向TypeScript社区提交建议以供考虑。至少他们可以解释这是否被排除以及为什么。
在您上面给出的特定情况下,我建议以下列方式明确地转换部分类型。
class GenericComponent<State extends BaseState> {
state: State;
constructor(state: State) {
this.state = state;
}
setState(partialState: Partial<State>) {
// Some logic here
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 } as State);
}
}
据我所知,此代码仍然是类型安全的,并且尊重State
上的约束。
答案 1 :(得分:0)
为什么不仅仅删除extends
关键字?
class GenericComponent {
state: BaseState;
constructor(state: BaseState) {
this.state = state;
}
setState(partialState: Partial<BaseState>) {
this.state = { ...this.state, ...partialState }; // error: Spread types may only be created from object types.
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // error: Argument of type '{ on: boolean; }' is not assignable to parameter of type 'Partial<State>'
}
}