From 81469e740a22b69d04e6ffc9951a41eaf41ab5fd Mon Sep 17 00:00:00 2001 From: Raymond Feng Date: Fri, 3 May 2019 08:09:10 -0700 Subject: [PATCH] chore(context): improve AsyncProxy with better names and more tests --- .../interception-proxy.acceptance.ts | 29 +++++++++++++++++++ packages/context/src/interception-proxy.ts | 10 +++---- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/packages/context/src/__tests__/acceptance/interception-proxy.acceptance.ts b/packages/context/src/__tests__/acceptance/interception-proxy.acceptance.ts index 80f51be56db2..b060cdc87929 100644 --- a/packages/context/src/__tests__/acceptance/interception-proxy.acceptance.ts +++ b/packages/context/src/__tests__/acceptance/interception-proxy.acceptance.ts @@ -60,6 +60,35 @@ describe('Interception proxy', () => { 'log: after-greet', 'convertName: after-greet', ]); + + // Make sure `greet` always return Promise now + expect(proxy.greet('Jane')).to.be.instanceOf(Promise); + }); + + it('creates async methods for the proxy', () => { + class MyController { + name: string; + + greet(name: string): string { + return `Hello, ${name}`; + } + + async hello(name: string) { + return `Hello, ${name}`; + } + } + + interface ExpectedAsyncProxyForMyController { + name: string; + greet(name: string): Promise; // the return type becomes `Promise` + hello(name: string): Promise; // the same as MyController + } + + const proxy = createProxyWithInterceptors(new MyController(), ctx); + + // Enforce compile time check to ensure the AsyncProxy typing works for TS + // tslint:disable-next-line:no-unused + const check: ExpectedAsyncProxyForMyController = proxy; }); it('invokes interceptors on a static method', async () => { diff --git a/packages/context/src/interception-proxy.ts b/packages/context/src/interception-proxy.ts index abd1cbfb4e4f..413d169784b5 100644 --- a/packages/context/src/interception-proxy.ts +++ b/packages/context/src/interception-proxy.ts @@ -7,18 +7,18 @@ import {Context} from './context'; import {InvocationArgs, invokeMethodWithInterceptors} from './interceptor'; /** - * The Promise type for `T`. If `T` extends `Promise`, the type is `T`, + * Create the Promise type for `T`. If `T` extends `Promise`, the type is `T`, * otherwise the type is `Promise`. */ -export type PromiseType = T extends Promise ? T : Promise; +export type AsPromise = T extends Promise ? T : Promise; /** * The async variant of a function to always return Promise. If T is not a * function, the type is `T`. */ // tslint:disable-next-line:no-unused (possible tslint bug to treat `R` as unused) -export type AsyncType = T extends (...args: InvocationArgs) => infer R - ? (...args: InvocationArgs) => PromiseType +export type AsAsyncFunction = T extends (...args: InvocationArgs) => infer R + ? (...args: InvocationArgs) => AsPromise : T; /** @@ -49,7 +49,7 @@ export type AsyncType = T extends (...args: InvocationArgs) => infer R * } * ``` */ -export type AsyncProxy = {[P in keyof T]: AsyncType}; +export type AsyncProxy = {[P in keyof T]: AsAsyncFunction}; /** * A proxy handler that applies interceptors