title: Can I infer types from input arguments?
body: <p>Can types be inferred from an options object?</p>
  <p>Here is my contrived example.</p>
  <p>The idea here is I have a function that takes in an object, where fields are conversion functions (convert A to B, etc). The return of this function is an object with similar functions, but they have a slightly different return type.</p>
  <p>I've put some generics in but I'm not really sure how to make it work. I've seen a similar design with Redux Toolkit's <code>createSlice()</code> function, but it's pretty complicated.</p>
  <pre><code>type InputActionFn = (arg: any) =&gt; any;
  interface Options {
      actions: {
          [K: string]: InputActionFn;
      };
  }
  
  interface ActionPayload&lt;B&gt; {
      payload: B;
  }
  type OutputActionFn&lt;A, B&gt; = (arg: A) =&gt; ActionPayload&lt;B&gt;;
  
  interface ConverterReturn {
      actions: {
          [K: string]: OutputActionFn&lt;any, any&gt;;
      };
  }
  
  export function createConvertor(options: Options): ConverterReturn {
      const actions: Record&lt;string, OutputActionFn&lt;any, any&gt;&gt; = {};
  
      // For each key I create a function that returns my converted payload.
      Object.keys(options.actions).forEach(key =&gt; {
          actions[key] = arg =&gt; {
              return {
                  payload: options.actions[key](arg),
              };
          };
      });
  
      return {
          actions,
      };
  }
  </code></pre>
  <p>And this is how I plan on using it:</p>
  <pre><code>// I can specify as many converter functions here as I want
  const conv = createConvertor({
      actions: {
          actionA: (a: number) =&gt; a.toFixed(),
          actionB: (b: string) =&gt; parseInt(b, 10),
      },
  });
  
  // actionA should be typed properly like this:
  //   actionA(arg: number) =&gt; ActionPayload&lt;string&gt;
  const resultA = conv.actions.actionA(5);
  console.log(resultA.payload);
  // Outputs: &quot;5&quot;
  
  const resultB = conv.actions.actionB('10');
  console.log(resultB.payload);
  // Outputs: 10
  </code></pre>