Skip to content

Commit 19fbb37

Browse files
committed
Expose helper types for working with client types
1 parent 0610a82 commit 19fbb37

File tree

4 files changed

+33
-12
lines changed

4 files changed

+33
-12
lines changed

package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"lint-staged": "^9.2.0",
9090
"prettier": "^1.19.1",
9191
"rimraf": "^3.0.0",
92+
"ts-expect": "^1.1.0",
9293
"ts-jest": "^24.0.2",
9394
"typescript": "^3.7.4"
9495
},

src/index.spec.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import * as t from "io-ts";
22
import { isLeft, isRight } from "fp-ts/lib/Either";
3+
import { expectType, TypeEqual } from "ts-expect";
34
import {
45
createServer,
56
parse,
67
createClient,
78
RpcError,
8-
Resolvers
9+
Resolvers,
10+
ClientRequests,
11+
ClientResponse
912
} from "./index";
1013

1114
describe("json rpc", () => {
@@ -28,6 +31,13 @@ describe("json rpc", () => {
2831
const server = createServer(methods, resolvers);
2932
const client = createClient(methods, x => server(x, undefined));
3033

34+
describe("types", () => {
35+
type Requests = ClientRequests<typeof methods>;
36+
type Responses = ClientResponse<typeof methods, Requests>;
37+
38+
expectType<TypeEqual<Responses, string>>(true);
39+
});
40+
3141
describe("parse", () => {
3242
it("should parse json", () => {
3343
const result = parse("{}");

src/index.ts

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,22 @@ export function createServer<T extends Methods, C = void>(
253253
/**
254254
* Map methods to valid client methods.
255255
*/
256-
type ClientMethods<T extends Methods> = {
256+
export type ClientRequests<T extends Methods> = {
257257
[K in keyof T]: {
258258
method: K;
259259
params: TypeOf<T[K]["request"]>;
260260
async?: boolean;
261261
};
262262
}[keyof T & string];
263263

264+
/**
265+
* Map client requests to response types.
266+
*/
267+
export type ClientResponse<
268+
T extends Methods,
269+
P extends ClientRequests<T>
270+
> = P["async"] extends true ? undefined : TypeOf<T[P["method"]]["response"]>;
271+
264272
/**
265273
* Configure client options.
266274
*/
@@ -283,7 +291,7 @@ export function createClient<T extends Methods, U = void>(
283291
let counter = 0;
284292
const jsonrpc = "2.0";
285293

286-
function prepare<U extends ClientMethods<T>>(payload: U) {
294+
function prepare<U extends ClientRequests<T>>(payload: U) {
287295
const { method, params, async } = payload;
288296
const { request, response } = methods[method];
289297

@@ -334,28 +342,24 @@ export function createClient<T extends Methods, U = void>(
334342
};
335343
}
336344

337-
async function rpcClient<P extends ClientMethods<T>>(
345+
async function rpcClient<P extends ClientRequests<T>>(
338346
payload: P,
339347
options: U
340-
): Promise<
341-
P["async"] extends true ? undefined : TypeOf<T[P["method"]]["response"]>
342-
> {
348+
): Promise<ClientResponse<T, P>> {
343349
const { params, id, method, process } = prepare(payload);
344350
const data = await send({ jsonrpc, method, params, id }, options);
345351
const response = process(data) as any;
346352
if (response instanceof RpcError) throw response; // Throw RPC errors.
347353
return response;
348354
}
349355

350-
rpcClient.many = async <P extends ClientMethods<T>[]>(
356+
rpcClient.many = async <P extends ClientRequests<T>[]>(
351357
payload: P,
352358
options: U
353359
): Promise<
354360
{
355-
[K in keyof P]: P[K] extends ClientMethods<T>
356-
? P[K]["async"] extends true
357-
? undefined
358-
: TypeOf<T[P[K]["method"]]["response"]> | RpcError
361+
[K in keyof P]: K extends number
362+
? ClientResponse<T, P[K]> | RpcError
359363
: P[K];
360364
}
361365
> => {

0 commit comments

Comments
 (0)