UNPKG

@cloudpss/ubrpc

Version:

Rpc server/client build on websocket and ubjson.

91 lines (77 loc) 3.23 kB
/* eslint-disable @typescript-eslint/no-explicit-any */ import type { InteropObservable, Observable } from 'rxjs'; /** 可转换为 Observable 的类型 */ export type ObservableLike<T> = Observable<T> | InteropObservable<T> | AsyncIterable<T>; /** Returns a boolean for whether the two given types are equal. */ type IsEqual<A, B> = (<G>() => G extends A ? 1 : 2) extends <G>() => G extends B ? 1 : 2 ? true : false; /** 作为通知输出的方法 */ type IsNotificationReturn<R> = IsEqual<R, void> extends true ? true : IsEqual<R, undefined> extends true ? true : R extends PromiseLike<void> | void ? true : false; /** 作为 Observable 输出的方法 */ type ObservableReturn = ObservableLike<any> | PromiseLike<ObservableLike<any>>; /** 提取类型中的方法 */ export type Methods<T> = { [P in keyof T]: T[P] extends (...args: any[]) => infer R ? (R extends ObservableReturn ? never : P) : never; }[keyof T] & string; /** 提取类型中的通知 */ export type Notifications<T> = { [P in keyof T]: T[P] extends (...args: any[]) => infer R ? IsNotificationReturn<R> extends true ? P : never : never; }[keyof T] & string; /** 提取类型中的订阅主题 */ export type Subjects<T> = { [P in keyof T]: T[P] extends (...args: any[]) => ObservableReturn ? P : never; }[keyof T] & string; /** RPC 调用的参数 */ export type RpcParameters<T> = T extends (...args: infer R) => any ? R : never; /** RPC 调用的返回 */ type RpcReturnsMap<R> = Awaited<R> extends ObservableLike<infer U> ? U : Awaited<R>; /** RPC 调用的返回 */ export type RpcReturns<T> = T extends (...args: any[]) => infer R ? RpcReturnsMap<R> : never; /** RPC 调用函数的实现 */ type RpcField<T> = T extends (...args: infer P) => infer R ? Awaited<R> extends ObservableReturn ? (...args: P) => ObservableLike<RpcReturnsMap<R>> | PromiseLike<ObservableLike<RpcReturnsMap<R>>> : (...args: P) => RpcReturnsMap<R> | PromiseLike<RpcReturnsMap<R>> : never; /** RPC 调用对象的实现 */ export type RpcObject<T> = { [K in keyof T as K & (Subjects<T> | Methods<T>)]: RpcField<T[K]>; }; // interface A { // field: number; // /** methodA */ // methodA(x: number): number | undefined; // methodB: (x: string, y: number) => Promise<number>; // readonly methodC: () => Iterable<number>; // readonly methodD: () => void | Promise<null | undefined>; // readonly notificationA: () => undefined; // readonly notificationB: () => Promise<void>; // notificationC(): void; // readonly notificationD: () => void | PromiseLike<undefined>; // readonly notificationE: () => void | Promise<void>; // subjectA(x: number): Observable<number>; // subjectB: (x: string) => Promise<Observable<number>>; // subjectC: () => PromiseLike<InteropObservable<number>>; // subjectD: () => AsyncGenerator<number>; // subjectE: () => PromiseLike<AsyncGenerator<number>>; // } // type X = Methods<A>; // type Y = Subjects<A>; // type Z = Notifications<A>; // type R = RpcObject<A>; // type Test = R['field']; // declare const r: R; // r.subjectA;