将typescript签名从对象提取到接口中

将typescript签名从对象提取到接口中,typescript,interface,react-redux,typescript-typings,Typescript,Interface,React Redux,Typescript Typings,我有一个习惯,在用redux传递信息时,我似乎重复了很多打字。当界面道具都在ActionCreators中定义时,有没有办法自动生成它们?请参阅下面的代码: import { bindActionCreators, Dispatch } from "redux"; const ActionCreators = { foo: (a: string): string => ("foo" + a), bar: (a: number): string => ("bar" + a),

我有一个习惯,在用redux传递信息时,我似乎重复了很多打字。当界面道具都在ActionCreators中定义时,有没有办法自动生成它们?请参阅下面的代码:

import { bindActionCreators, Dispatch } from "redux";
const ActionCreators = {
  foo: (a: string): string => ("foo" + a),
  bar: (a: number): string => ("bar" + a),
  baz: (a: boolean): number => (a ? 256 : 123)
};

interface Props {
  foo: (a: string) => string;
  bar: (a: number) => string;
  baz: (a: boolean) => number;
}

const mapDispatchToProps = (dispatch: Dispatch): Props => {
  return bindActionCreators(ActionCreators, dispatch);
};

理解bindActionCreators并不是必需的,这里真正的问题是获取ActionCreators上的所有签名,并将其提取到一个界面,如Props。

您可以使用
typeof
type操作符获取任何常量的类型。然后可以使用类型别名为其命名

const ActionCreators = {
  foo: (a: string): string => ("foo" + a),
  bar: (a: number): string => ("bar" + a),
  baz: (a: boolean): number => (a ? 256 : 123)
};

type Props = typeof ActionCreators;
/*
Same as
type Props = {
  foo: (a: string) => string;
  bar: (a: number) => string;
  baz: (a: boolean) => number;
} 
*/
虽然在这种情况下接口和类型别名之间存在细微差异,但它们应该是等效的

编辑

注释中的后续问题:如何将所有成员函数的返回类型更改为void

为此,需要使用映射类型将原始类型映射到新类型,使用条件类型提取原始函数的参数类型:

type ArgumentTypes<T> = T extends (...a: infer A) => any ? A: [] //Conditional type extracts the argument types
type Props = {
  // Mapped type, maps the keys of the original type to a new type
  // with the same keys, and with each key being a function with the same argument as the original 
  // but returning void.
  [P in keyof typeof ActionCreators]: (...a: ArgumentTypes<typeof ActionCreators[P]>) => void
}
type-ArgumentTypes=T扩展(…a:推断a)=>any?A:[]//条件类型提取参数类型
类型道具={
//映射类型,将原始类型的键映射到新类型
//使用相同的键,并且每个键都是与原始键具有相同参数的函数
//但回归虚空。
[P in keyof typeof ActionCreators]:(…a:ArgumentTypes)=>void
}

这很容易。谢谢实际上,我还想将Props中的返回值更改为void。这也算是小事吗?@Mamen先生不是小事,nu bo也有那么难,我会把它添加到答案中shortly@MrMamen我将答案添加到后续内容中,别忘了向上投票;)