将对象的打字稿签名提取到接口中

时间:2018-11-21 09:58:47

标签: typescript interface react-redux typescript-typings

我有一个习惯,当我在redux中传递信息时,我似乎重复很多打字。在ActionCreators中定义它们后,是否有任何方法可以自动生成接口Props?请参见下面的代码:

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之类的接口中。

1 个答案:

答案 0 :(得分:1)

您可以只使用typeof类型运算符来获取任何常量的类型。然后,您可以使用类型别名为其命名

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
}