Skip to content

Commit

Permalink
feat(messaging): Simplify protocol map definitions with function types (
Browse files Browse the repository at this point in the history
#21)

Co-authored-by: Aaron Klinker <[email protected]>
  • Loading branch information
noamloewenstern and aklinker1 authored Mar 17, 2023
1 parent d742384 commit a91196d
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 4 deletions.
36 changes: 36 additions & 0 deletions packages/messaging/src/index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,32 @@ describe('Messenger Typing', () => {
expectTypeOf(onMessage).parameter(1).returns.resolves.toBeBoolean();
});

it('should infer data and return types from bound function declaration', () => {
const { sendMessage, onMessage } = defineExtensionMessaging<{
getStringLength(data: string): number;
}>();

expectTypeOf(sendMessage).parameter(0).toMatchTypeOf<'getStringLength'>();
expectTypeOf(sendMessage).parameter(1).toBeString();
expectTypeOf(sendMessage).returns.resolves.toBeNumber();

expectTypeOf(onMessage).parameter(1).parameter(0).toHaveProperty('data').toBeString();
expectTypeOf(onMessage).parameter(1).returns.resolves.toBeNumber();
});

it('should infer data and return types from anonymous function declaration', () => {
const { sendMessage, onMessage } = defineExtensionMessaging<{
getStringLength: (data: string) => number;
}>();

expectTypeOf(sendMessage).parameter(0).toMatchTypeOf<'getStringLength'>();
expectTypeOf(sendMessage).parameter(1).toBeString();
expectTypeOf(sendMessage).returns.resolves.toBeNumber();

expectTypeOf(onMessage).parameter(1).parameter(0).toHaveProperty('data').toBeString();
expectTypeOf(onMessage).parameter(1).returns.resolves.toBeNumber();
});

it('should require passing undefined to sendMessage when there is no data', () => {
const { sendMessage } = defineExtensionMessaging<{
ping: ProtocolWithReturn<undefined, 'pong'>;
Expand All @@ -48,4 +74,14 @@ describe('Messenger Typing', () => {
expectTypeOf(sendMessage).parameter(1).toBeUndefined();
expectTypeOf(sendMessage).parameter(2).toEqualTypeOf<number | undefined>();
});

it('should require passing undefined to sendMessage when there is no arguments in a function definition', () => {
const { sendMessage } = defineExtensionMessaging<{
ping(): 'pong';
}>();

expectTypeOf(sendMessage).parameter(0).toMatchTypeOf<'ping'>();
expectTypeOf(sendMessage).parameter(1).toBeUndefined();
expectTypeOf(sendMessage).parameter(2).toEqualTypeOf<number | undefined>();
});
});
18 changes: 14 additions & 4 deletions packages/messaging/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,24 @@ export interface ExtensionMessagingConfig {
export type ProtocolWithReturn<TData, TReturn> = { BtVgCTPYZu: TData; RrhVseLgZW: TReturn };

/**
* Given a `ProtocolWithReturn` or a value, return the message's data type.
* Given a function declaration, `ProtocolWithReturn`, or a value, return the message's data type.
*/
export type GetDataType<T> = T extends ProtocolWithReturn<any, any> ? T['BtVgCTPYZu'] : T;
export type GetDataType<T> = T extends (...args: infer Args) => any
? Args['length'] extends 0 | 1
? Args[0]
: never
: T extends ProtocolWithReturn<any, any>
? T['BtVgCTPYZu']
: T;

/**
* Given a `ProtocolWithReturn` or a value, return the message's return type.
* Given a function declaration, `ProtocolWithReturn`, or a value, return the message's return type.
*/
export type GetReturnType<T> = T extends ProtocolWithReturn<any, any> ? T['RrhVseLgZW'] : void;
export type GetReturnType<T> = T extends (...args: any[]) => infer R
? R
: T extends ProtocolWithReturn<any, any>
? T['RrhVseLgZW']
: void;

/**
* Either a Promise of a type, or that type directly. Used to indicate that a method can by sync or
Expand Down

0 comments on commit a91196d

Please sign in to comment.