从减速器功能推断类型

时间:2019-07-17 12:51:45

标签: typescript

我有一种基于2-3种类型的减速器类型。 StoreReturnStoreContext(默认为void)。

如何在CountReducer类型中重用Action类型作为类型参数?

现在,Action要求使用与CountReducer相同的2-3种类型,从而创建重复的代码并使API令人困惑。

当前代码:

type CountingStore = {
  state: "counting";
  ctx: number;
};

type Store = StartedStore | CountingStore | EndedStore;

type CountReducer = (s: Store, toAdd: number) => CountingStore;

const CountReducer: CountReducer = (s, toAdd) => ({
  state: "counting",
  ctx: s.ctx + toAdd
});
type Action<Store, ReturnStore, Context = void> = {
  act: (() => void) | ((ctx: Context) => void);
  stream: Observable<Context>;
  reducer: Reducer<Store, ReturnStore, Context>;
};

type Actions = {
  count: Action<Store, CountingStore, number>;
  end: Action<Store, EndedStore>;
  restart: Action<Store, StartedStore>;
};

未来可能的API设计:

type Action<MyReducer extends Reducer> = "???";

您可以在以下可运行的项目中找到相关的源代码:https://github.com/marcusnielsen/rx-machine/blob/master/src/index.test.ts

1 个答案:

答案 0 :(得分:2)

您可以使用条件类型从reducer函数中提取类型参数:

type ActionFromReducer<T extends (s: any, ctx?: any) => any> =  
  T extends (s: infer TStore, ctx: infer TContext) => infer TReturnStore ? Action<TStore, TReturnStore, TContext> : 
  T extends (s: infer TStore) => infer TReturnStore ? Action<TStore, TReturnStore, > : 
  never;
type Actions = {
  count: ActionFromReducer<CountReducer>;
  end: ActionFromReducer<EndReducer>;
  restart: ActionFromReducer<RestartReducer>;
};