Last active
February 20, 2023 02:07
-
-
Save ebrahimmfadae/1d1da46b176e7c2ffa56f0e91b801e8d to your computer and use it in GitHub Desktop.
Pure typescript solution to infer `params` and `meta` types in `call` and `mcall`
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
CallingOptions, | |
Context, | |
MCallCallingOptions, | |
MCallDefinition, | |
ServiceActionsSchema, | |
ServiceBroker, | |
} from 'moleculer' | |
import { AllActionsUnion } from './actions' | |
type Resolve<T> = T extends PromiseLike<infer R> ? R : T | |
type RemoveIndex<T> = { | |
[K in keyof T as string extends K ? never : number extends K ? never : K]: T[K] | |
} | |
type ContextParam<T> = T extends Context<infer P> ? P : unknown | |
type ActionContext<T extends keyof AllActionsUnion> = Parameters<AllActionsUnion[T]>[0] | |
type XMCallDefinition<T extends string> = T extends keyof AllActionsUnion | |
? Omit<Partial<MCallDefinition<ContextParam<ActionContext<T>>>>, 'action'> & { action: T } | |
: never | |
type ActionReturnType<T extends keyof AllActionsUnion> = Resolve<ReturnType<AllActionsUnion[T]>> | |
type XCallingOptions<T> = T extends Context<any, infer M> | |
? CallingOptions & { meta?: Partial<M> } | |
: CallingOptions | |
type ExtendCallMethod<T extends keyof AllActionsUnion = keyof AllActionsUnion> = { | |
call<K extends T>(actionName: K): Promise<ActionReturnType<K>> | |
call<K extends T>( | |
actionName: K, | |
params: ContextParam<ActionContext<K>>, | |
opts?: XCallingOptions<ActionContext<K>>, | |
): Promise<ActionReturnType<K>> | |
mcall<U extends Record<string, XMCallDefinition<T>>>( | |
def: U, | |
opts?: MCallCallingOptions, | |
): Promise<{ [K in keyof U]: ActionReturnType<U[K]['action']> }> | |
mcall<U extends XMCallDefinition<keyof AllActionsUnion>[]>( | |
def: [...U], | |
opts?: MCallCallingOptions, | |
): Promise<{ [K in keyof U]: ActionReturnType<U[K]['action']> }> | |
} | |
type XServiceBroker = Omit<RemoveIndex<ServiceBroker>, 'call' | 'mcall'> & ExtendCallMethod | |
type XContext<P = unknown, M extends object = {}> = Omit< | |
Context<P, M>, | |
'call' | 'mcall' | 'broker' | |
> & | |
ExtendCallMethod & { broker: XServiceBroker } | |
export const createActions = <T extends ServiceActionsSchema>(actions: T) => actions | |
export const xContext = <P, M extends object>(ctx: Context<P, M>) => ctx as XContext<P, M> | |
export const xBroker = (broker: ServiceBroker) => broker as XServiceBroker |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { ActionSchema, ServiceActionsSchema } from 'moleculer' | |
import type * as HealthCheck from './services/healthCheck.service' | |
type ServiceMap<S extends ServiceActionsSchema, V extends string, N extends string> = { | |
[K in keyof S as `${V}.${N}.${K & string}`]: S[K] extends ActionSchema ? S[K]['handler'] : S[K] | |
} | |
export type AllActionsUnion = ServiceMap<HealthCheck.Actions, HealthCheck.Version, HealthCheck.Name> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createActions } from '../x.moleculer' | |
const name = 'healthCheck' | |
const version = 1 | |
const actions = createActions({ | |
check() { | |
return 'Works' | |
}, | |
}) | |
/** | |
* You can declare actions using satisfies keyword in Typescript 4.9+ | |
* | |
* const actions = { | |
* check() { | |
* return 'Works' | |
* }, | |
* } satisfies ServiceActionsSchema | |
*/ | |
export type Actions = typeof actions | |
export type Name = typeof name | |
export type Version = `v${typeof version}` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
xContext(ctx).call('v1.healthCheck.check') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment