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インターフェイスを直接使用してもエラーは発生しません。 StateジェネリックはBaseState明示的に拡張するため、 GenericComponentクラスからも同じ動作が期待されます。

実際の動作:
代わりに、 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のタイプ引数の制約を満たしますが、これは_すべての_タ​​イプに当てはまりませんTここでTは、 Statefulの型引数の制約を満たします。

したがって、上記の誤ったコードは、すべてのタイプのT<T>T,ステートフルであると主張しています。`。

論理的には、次のように見ることができます。

アサーション

  1. Pタイプ{ on: boolean }
  2. TPに割り当て可能であるようなすべてのタイプTについて、上記のStateful<T>の定義は有効です。

反例による反証

  1. Uタイプ{ on: boolean, value: number }
  2. Uは定義上P ->に割り当てることができます
  3. Stateful<U>は無効です->置換による
  4. したがって、 TP割り当て可能で、 Stateful<T>が無効なインスタンス化であるようなタイプTが存在します->含意によって

@RyanCavanaugh @aluanhaddadシュート、私はそれを知っていました。 問題をもっと単純なものに絞り込もうとしているときに、私は混乱しました。 もう一度試してみましょう。 この場合、パーシャルを使用するのはどうですか? それでも同様のエラーが発生します。

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 評価

関連する問題

jbondc picture jbondc  ·  3コメント

kyasbal-1994 picture kyasbal-1994  ·  3コメント

weswigham picture weswigham  ·  3コメント

dlaberge picture dlaberge  ·  3コメント

Antony-Jones picture Antony-Jones  ·  3コメント