将typescript签名从对象提取到接口中
我有一个习惯,在用redux传递信息时,我似乎重复了很多打字。当界面道具都在ActionCreators中定义时,有没有办法自动生成它们?请参阅下面的代码:将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),
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我将答案添加到后续内容中,别忘了向上投票;)