Flow v0.57
I'd like to define 2 function types, Foo and FancyFoo to help type check the following pattern:
const fooFn = () => ({ id: '...', type: '...' });
fooFn['HELLO'] = 'WORLD';
fooFn['test'] = () => {};
...
// now I can do this:
fooFn();
fooFn.HELLO;
fooFn.test();
The first function type is seemingly straightforward:
type Foo = () => {
  id :string,
  type :string
}
I'm stuck figuring out the second. It's not clear to me how to build off of function types.
I tried using intersection:
type FancyFoo = Foo & {
  HELLO :string,
  test :() => mixed
}
However, this approach fails:
// Errors:
2: type FancyFoo = Foo & {
                         ^ property `HELLO` of object type. Property not found in
7: const fooFn :FancyFoo = () => ({ id: '...', type: '...' });
                           ^ function
2: type FancyFoo = Foo & {
                         ^ property `test` of object type. Property not found in
7: const fooFn :FancyFoo = () => ({ id: '...', type: '...' });
                           ^ function
How do I define a FancyFoo function type that "extends" Foo but also includes the extra properties?
Link to Flow Try
UPDATE
Here's a more specific example for what I'm trying to do:
type Foo = () => { id :string, type :string }
export function getFancyFoo(type :string) :FancyFoo {
  const id :string = randomId();
  const foo :Foo = getFoo(id, type);
  ['A', 'B', 'C'].forEach((thing :string) => {
    foo[thing.toUpperCase()] = thing.toUpperCase();
    foo[thing.toLowerCase()] = () => { /* function that does fancy thing */ };
  });
  return foo;
}
The getFancyFoo function will first get a Foo function, and then decorate/enhance it with extra properties. At the end of the function, foo will look like this (Chrome Dev Tools):

FancyFoo is a Foo function, but it also has the extra properties added to it. I'm stuck on defining the FancyFoo function type. 
Use Callable Object syntax, e.g.
type OutputInterceptorType = {|
  <T>(routine: () => Promise<T> | T): Promise<T>,
  output: ''
|};
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With