Typescript: 将两个通用参数相交以形成第三个参数不视为等效

创建于 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 }>( ... );

这是R1R2R的有效实例,但是R1 & R2不能分配给R因为它缺少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 }>( ... );

这是R1R2R的有效实例,但是R1 & R2不能分配给R因为它缺少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 等级