From fa27dda530f57ef55a04d5f16295260f7b99a3ae Mon Sep 17 00:00:00 2001 From: Jerko Steiner Date: Thu, 1 Aug 2019 13:57:51 +0700 Subject: [PATCH] Add ability to infer jsonrpc redux action types --- packages/jsonrpc/src/redux.test.ts | 41 ++++++++++++++++++++++- packages/jsonrpc/src/types.ts | 53 ++++++++++++++++++++++++++---- 2 files changed, 87 insertions(+), 7 deletions(-) diff --git a/packages/jsonrpc/src/redux.test.ts b/packages/jsonrpc/src/redux.test.ts index 158bde3..7b1698f 100644 --- a/packages/jsonrpc/src/redux.test.ts +++ b/packages/jsonrpc/src/redux.test.ts @@ -10,12 +10,14 @@ import {createReduxClient} from './redux' import {createRemoteClient} from './remote' import {jsonrpc} from './express' import {keys} from 'ts-transformer-keys' +import {TActionCreators, TAllActions} from './types' describe('createReduxClient', () => { interface IService { add(a: number, b: number): number addAsync(a: number, b: number): Promise + addStringsAsync(a: string, b: string): Promise addWithContext(a: number, b: number): (ctx: IContext) => number addAsyncWithContext(a: number, b: number): (ctx: IContext) => Promise @@ -32,6 +34,9 @@ describe('createReduxClient', () => { addAsync(a: number, b: number) { return new Promise(resolve => resolve(a + b)) } + addStringsAsync(a: string, b: string) { + return new Promise(resolve => resolve(a + b)) + } addWithContext = (a: number, b: number) => (ctx: IContext) => a + b + ctx.userId addAsyncWithContext = (a: number, b: number) => (ctx: IContext) => @@ -63,7 +68,41 @@ describe('createReduxClient', () => { function getClient() { const remoteClient = createRemoteClient( baseUrl, '/service', keys()) - return createReduxClient(remoteClient, 'myService') + const client = createReduxClient(remoteClient, 'myService') + + // type R = T extends (...args: any[]) => infer RV ? RV : never + + type Client = typeof client + type ActionCreators = TActionCreators + type AllActions = TAllActions + + function handleAction(state: any, action: AllActions) { + if (action.type !== 'myService') { + return + } + switch (action.method) { + case 'add': + switch (action.status) { + case 'pending': + const p1: Promise = action.payload + return + case 'rejected': + const p2: Error = action.payload + return + case 'resolved': + const p3: number = action.payload + return + } + case 'addAsync': + // case 'addAsync1234': + // case + } + } + + // type Values = T[keyof T] + // type C = ReturnType> + + return client } describe('action creators', () => { diff --git a/packages/jsonrpc/src/types.ts b/packages/jsonrpc/src/types.ts index 49d6416..46666b6 100644 --- a/packages/jsonrpc/src/types.ts +++ b/packages/jsonrpc/src/types.ts @@ -6,15 +6,56 @@ type RetProm = T extends Promise ? T : Promise type PromisifyReturnType = (...a: ArgumentTypes) => RetProm>> +import {IPendingAction, IResolvedAction, IRejectedAction} from '@rondo/client' + export type TAsyncified = { [K in keyof T]: PromisifyReturnType } export type TReduxed = { - [K in keyof T]: (...a: ArgumentTypes) => { - type: ActionType - payload: RetProm>> - method: K - status: 'pending' - } + // [K in keyof T]: (...a: ArgumentTypes) => { + // type: ActionType + // payload: RetProm>> + // method: K + // status: 'pending' + // } + // [K in keyof T]: (...a: ArgumentTypes) => + // IPendingAction>>, ActionType> & { + // method: K, + // } + [K in keyof T]: (...a: ArgumentTypes) => + IRPCPendingAction>, ActionType, K> } + +export interface IRPCPendingAction< + T, ActionType extends string, Method extends string | number | symbol +> extends IPendingAction { + method: Method +} + +export interface IRPCResolvedAction< + T, ActionType extends string, Method extends string | symbol | number +> extends IResolvedAction { + method: Method +} + +export interface IRPCRejectedAction< + ActionType extends string, Method extends string | symbol | number +> extends IRejectedAction { + method: Method +} + +export type TResolved = + A extends IRPCPendingAction + ? IRPCResolvedAction + : never + +export type TRejected = + A extends IRPCPendingAction + ? IRPCRejectedAction + : never + +type Values = T[keyof T] +export type TActionCreators = RetType> +export type TAllActions = TActionCreators + | TResolved> | TRejected>