Typescript: 3番目を形成するための2つのジェネリックパラメーターの交差は同等として認識されません

作成日 2019年01月13日  ·  3コメント  ·  ソース: microsoft/TypeScript


TypeScriptバージョン: 3.3.0-dev.201xxxxx


検索ワード:

ジェネリック医薬品の交差点

コード

let connect = <R1,R2, R = R1&R2 >(mapState2Props: (state) => R1, mapDispatch2Props: (dispatch: any) => R2): R => {
  let state = {};
  let dispatch = () => { };
  return { ...mapState2Props(state), ...mapDispatch2Props(dispatch)}
}

予想される行動:
汎用署名でR = R1&R2を定義したので、これは有効であると思います。

実際の動作:

returnステートメントでエラーType 'R1 & R2' is not assignable to type 'R'.を取得します。 R extends R1&R2も試しましたが、同じエラーが発生します。

遊び場リンク:

リンク

関連する問題:

https://github.com/Microsoft/TypeScript/issues/5823

Question

最も参考になるコメント

ここでのエラーは正しいと思います。 はいR1 & R2はデフォルトのRに割り当てることができますが、 Rは_more_特定のタイプでインスタンス化される場合があります。 次のインスタンス化を検討してください。

connect<{ x: number; }, { y: number; }, { x: number, y: number, z: number }>( ... );

これはR1R2 、およびR有効なインスタンス化ですが、 R1 & R2R割り当てられないため、割り当てられません。 zパラメータ。

あなたの例では、 Rパラメーターは実際には必要ありません(実際のユースケースはもっと複雑かもしれませんが)。 これは機能します:

let connect = <R1,R2>(mapState2Props: (state) => R1, mapDispatch2Props: (dispatch: any) => R2): R1 & R2 => {
  let state = {};
  let dispatch = () => { };
  return { ...mapState2Props(state), ...mapDispatch2Props(dispatch)}
}

全てのコメント3件

ここでのエラーは正しいと思います。 はいR1 & R2はデフォルトのRに割り当てることができますが、 Rは_more_特定のタイプでインスタンス化される場合があります。 次のインスタンス化を検討してください。

connect<{ x: number; }, { y: number; }, { x: number, y: number, z: number }>( ... );

これはR1R2 、およびR有効なインスタンス化ですが、 R1 & R2R割り当てられないため、割り当てられません。 zパラメータ。

あなたの例では、 Rパラメーターは実際には必要ありません(実際のユースケースはもっと複雑かもしれませんが)。 これは機能します:

let connect = <R1,R2>(mapState2Props: (state) => R1, mapDispatch2Props: (dispatch: any) => R2): R1 & R2 => {
  let state = {};
  let dispatch = () => { };
  return { ...mapState2Props(state), ...mapDispatch2Props(dispatch)}
}

うーん、それは良い点です。 ここでの目標は、最終的に戻り値の型Rを指定して、 mapState2PropsmapDispatch2Props組み合わせると有効なRなる型の安全性を確保できる場所に到達すること

例えば:

interface IComponentProps{
  foo: string;
  doFoo: ()=>void
}
let props: IComponentProps = connect<IComponentProps>(
  (state) => { foo: state.foo },
  (dispatch) => {doFoo: () => dispatch('FOO')}
)

しかし...それが可能かどうかはわかりません...代わりにR1とR2をRサブセットとして定義する必要があるようですが、それらは相互に依存しています...

Rも完全に無関係なタイプである可能性があることに注意してください。 ジェネリックスのデフォルトの型引数は制約ではありません。

connect<{ a: string }, { b: number }, { c: boolean[] }>(() => ({ a: "a" }), () => ({ b: 3 }))
このページは役に立ちましたか?
0 / 5 - 0 評価