我正在构建一个应用程序,其中我有一些由更改器更改的状态。消费代码不应直接访问状态,而只能通过咖喱对变体进行按摩,从而使使用代码只需要调用部分应用的函数即可。
因此,而不是消费者调用:
setCount(state: State, firstArg: number, secondArg: number);
消费者应调用:
setCount(firstArg: number, secondArg: number)
为此,我有以下内容:
interface State {
count: number;
}
const state: State = {
count: 0
};
interface IMutators {
setCount: (state: State, firstArg: number, secondArg: number) => Partial<State>;
}
const mutators: IMutators = {
setCount: (state: State, firstArg: number, secondArg: number) => ({
count: state.count + x + y
})
};
type RemoveStateParam<T extends any[]> = ((...x: T) => {}) extends ((
h: State,
...t: infer R
) => {})
? R
: never;
type MutatorsWithoutState<M> = {
[P in keyof M]: M[P] extends (...args: any[]) => any
? (...args: RemoveStateParam<Parameters<M[P]>>) => Partial<State>
: never
};
type MutatorsInterface = MutatorsWithoutState<IMutators>;
interface Context {
mutators: MutatorsInterface;
}
const buildInterfaceFromImplementation = (
mutators: IMutators,
state: State
): MutatorsInterface => {
const newObj = {};
Object.keys(mutators).forEach(k => {
const mutator = mutators[k];
const curried = _.curry(mutator, 1);
const interfaceCompliantMutator = curried(state);
newObj[k] = interfaceCompliantMutator;
});
return newObj as MutatorsInterface;
};
const context: Context = {
mutators: buildInterfaceFromImplementation(mutators, state)
};
context.mutators.setCount(1, 2);
我想改进的是buildInterfaceFromImplementation
方法:
const newObj = {};
Object.keys(mutators).forEach(k => {
const mutator = mutators[k];
...
});
return newObj as MutatorsInterface;
是否有某种方法可以避免在最后一行使用演员表?我想像这样输入newObj
:
const newObj: MutatorsInterface = {}; // This obviously won't work