title: Properly type dynamic functions in a proxy using TypeScript
body: <p>I have a function that returns a Proxy which uses a <code>get</code> trap to infer functions from multiple objects. Now I need to be able to type these functions, since they are technically known at compile time but TypeScript just can't figure them out. How do make TypeScript recognize these functions to be able to add them to my interface?</p>
  
  <pre><code>interface IObject {
    (): IFunction;
    addAMethod(name: string, fn: (...args: any[]) =&gt; any): void;
  }
  
  interface IFunction {
    list: string[];
    option: boolean;
  }
  
  const mainFunc: IObject = Object.assign(
    (): IFunction =&gt; {
      const context = {
        list: [],
        option: true,
      };
  
      return new Proxy(context, handler);
    },
    {
      addAMethod(name: string, fn: (...args: any[]) =&gt; any) {
        Object.assign(core, fn);
      },
    },
  );
  
  const handler = {
    get(context: {[key: string]: any}, prop: string, receiver: IFunction) {
      if (prop in context) {
        return context[prop];
      }
      if (prop in core) {
        return core[prop];
      }
    },
  };
  
  const core = {
    evaluate: (val: any) =&gt; true,
    doSomething: (val: any) =&gt; false
  }
  
  export default mainFunc;
  </code></pre>
  
  <p>Now this would allow one to the following:</p>
  
  <pre><code>import mainFunc from "./mainFunc"
  
  mainFunc().evaluate('wow'); // Should return true
  </code></pre>
  
  <p>This of course does not return true but rather shows that <code>evaluate()</code> is not part of type <code>IFunction</code>, which is true. But when I try to add it I get another error, where I can't assign the function to <code>IFunction</code> because it does not define <code>evaluate()</code>.</p>
  
  <pre><code>// ...
  
  interface IFunction {
    list: string[];
    option: boolean;
    evaluate(val: any): boolean;
  }
  
  const mainFunc: IObject = Object.assign(
    (): IFunction =&gt; {
      const context = {
        list: [],
        option: true,
      };
  
      return new Proxy(context, handler); // Error happens here
    },
    // ...
  );
  
  // ...
  
  const core = {
    evaluate: (val: any) =&gt; true,
    doSomething: (val: any) =&gt; false
  }
  </code></pre>
  
  <blockquote>
    <p>Type '{ list: never[]; option: boolean; }' is not assignable to type 'IFunction'.
      Property 'evaluate' is missing in type '{ list: never[]; option: boolean; }'.</p>
  </blockquote>
  
  <p>Any idea how I could type <code>evaluate()</code>?</p>