Typescript: 无法使用泛型定义中的`extends'将兼容值分配给泛型类型的属性。

创建于 2017-04-07  ·  3评论  ·  资料来源: microsoft/TypeScript

TypeScript版本: 2.2.2

我可能只是误解了泛型的工作原理(如果是,请指出正确的方向),但这似乎是一个错误。

代码

// A *self-contained* demonstration of the problem follows...

interface BaseState {
    on: boolean;
};

class Component {
    state: BaseState;

    setState(state: BaseState) {
        this.state = state;
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 });  // no error
    }
}

class GenericComponent<State extends BaseState> {
    state: State;

    setState(state: State) {
        this.state = state
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 });  // error Argument of type '{ on: boolean; }' is not assignable to parameter of type 'State'.
    }
}

预期行为:
在上面的示例中的Component类中,直接使用BaseState接口时不会导致任何错误。 我期望GenericComponent类具有相同的行为,因为State泛型显式扩展了BaseState

实际行为:
相反,我得到与this.setState({ on: value > 0 });相关的以下错误:“类型'{的参数:on boolean;}'不能分配给类型'State'的参数。”

Question

最有用的评论

考虑一下如果您写这篇文章会发生什么

var t = new GenericComponent<{on: boolean, thing: string}>();
t.onInput({ value: 30 });
t.state.thing.substr(0); // 'thing' property should exist, but doesn't

所有3条评论

考虑一下如果您写这篇文章会发生什么

var t = new GenericComponent<{on: boolean, thing: string}>();
t.onInput({ value: 30 });
t.state.thing.substr(0); // 'thing' property should exist, but doesn't

这是一个简化的示例:

class Stateful<State extends { on: boolean }> {
  state: State = {
    on: true
  }; // error
}

这样做不起作用的原因是,只有在Stateful用与{ on: boolean }完全等效的类型参数实例化时,它才有效。

基本上,存在一个类型T ,满足Stateful类型参数的约束,使得实例化有效,但不包含_for all_类型T其中T满足Stateful的type参数的约束。

因此,上面的错误代码断言,对于所有类型T<T> ,其中T,有状态`。

从逻辑上讲,我们可以如下所示

断言

  1. 假设P为类型{ on: boolean }
  2. 对于T所有类型,例如T可分配给P ,上述Stateful<T>的定义有效

通过反例证明

  1. 假设U为类型{ on: boolean, value: number }
  2. U可分配给P ->
  3. Stateful<U>无效->通过替换
  4. 因此,存在类型T ,使得T可分配给PStateful<T>是无效的实例->暗示

@RyanCavanaugh @aluanhaddad射击,我知道。 我只是在试图将问题简化为更简单的东西时感到困惑。 因此,让我们再试一次。 在这种情况下使用Partial怎么办? 我仍然收到类似的错误。

interface BaseState {
    on: boolean;
};

class Component {
    state: BaseState;

    setState(partialState: Partial<BaseState>) {
        this.state = { ...this.state, ...partialState };
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 });  // no error
    }
}

class GenericComponent<State extends BaseState> {
    state: State;

    setState(partialState: Partial<State>) {
        this.state = { ...this.state, ...partialState };
    }

    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 / 5 - 0 等级