Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix Flow typings for flow() #2164

Merged
merged 6 commits into from Oct 22, 2019
Merged

fix Flow typings for flow() #2164

merged 6 commits into from Oct 22, 2019

Conversation

vonovak
Copy link
Contributor

@vonovak vonovak commented Oct 18, 2019

This fixes flow typings for flow() which are now fundamentally broken. Flow() returns a cancellable promise (fixed) and a signature that is not valid was removed.

usage:

// @flow
import { flow, type CancellablePromise } from 'mobx';

export class FlowTest {
  promise: CancellablePromise<string>;

  constructor() {
    this.promise = this.fetchSomeString(2);
    this.promise.cancel();
  }

  fetchSomeString = flow<string, number>(function*(pageNumber: number) {
    try {
      const someString = yield this.fetchStringSomehow(pageNumber);
      return someString;
    } catch (error) {
      return '123';
    }
  });

  fetchStringSomehow = (pageNumber: mixed): Promise<string> => {
    console.log(pageNumber);
    return Promise.resolve('123');
  };
}

PR checklist - I think none of these apply for this PR.

  • Added unit tests
  • Updated changelog
  • Updated /docs. For new functionality, at least API.md should be updated
  • Added typescript typings
  • Verified that there is no significant performance drop (npm run perf)

Feel free to ask help with any of these boxes!

The above process doesn't apply to doc updates etc.

@danielkcz
Copy link
Contributor

I believe this is duplicate to #2160 :) @xaviergonz what do you think, something useful here?

@xaviergonz
Copy link
Contributor

xaviergonz commented Oct 18, 2019

This seems to be a fix for flows too, but for "flow" (the facebook thingy) :)

That being said I think the declaration could be improved as

declare export function flow<R, Args extends any[]>(
  generator: (...args: Args) => Generator<any, R, any> | AsyncGenerator<any, R, any>
): (...args: Args) => CancellablePromise<R>

Like the TS one for the fix.

The one presented here (after the fix) has the same def duplicated twice and casts arguments as any[] rather than inferring them from the original function (though I'm not sure if facebook flow does support actually that).

Also in TS R | Promise<R> is not required in TS, but again I'm not an expert of facebook flow.

@xaviergonz
Copy link
Contributor

xaviergonz commented Oct 18, 2019

Nevermind about the definition duplication part, I just saw the extra name argument :) The other things might still apply though.

@xaviergonz
Copy link
Contributor

Wait, actually I don't think flows support a name argument at all, they seem to take the name from the inner generator function

@vonovak
Copy link
Contributor Author

vonovak commented Oct 21, 2019

@xaviergonz

I don't think flows support a name argument at all, they seem to take the name from the inner generator function

if you're talking about (?)

declare export function flow<T>(
    name: string,
    fn: (...args: any[]) => T
): (...args: any[]) => Promise<T>

then I have removed it because it does not match the signature of how it's implemented. Not sure why it was there.

As for the improvements you suggested

  • Args extends any[] - there is no such thing in Flow that I'm aware of

has the same def duplicated twice and casts arguments as any[] rather than inferring them from the original function (though I'm not sure if facebook flow does support actually that).

I'm not aware of such support. The best I can think of is having this - I'm in favor of adding this if you agree because it's more accurate.

declare export function flow<T>(
    fn: () => Generator<any, T | Promise<T>, any>
): () => CancellablePromise<T>

declare export function flow<T, A>(
    fn: (A) => Generator<any, T | Promise<T>, any>
): (A) => CancellablePromise<T>

declare export function flow<T, A, B>(
    fn: (A, B) => Generator<any, T | Promise<T>, any>
): (A, B) => CancellablePromise<T>

// and so on, until let's, say 4 params?

Also in TS R | Promise is not required in TS, but again I'm not an expert of facebook flow.

this is required in Flow

@vonovak vonovak marked this pull request as ready for review October 21, 2019 11:12
@xaviergonz
Copy link
Contributor

if you're talking about (?)

declare export function flow<T>(
    name: string,
    fn: (...args: any[]) => T
): (...args: any[]) => Promise<T>

then I have removed it because it does not match the signature of how it's implemented. Not sure why it was there.

Yep, exactly :)

As for the improvements you suggested

  • Args extends any[] - there is no such thing in Flow that I'm aware of

has the same def duplicated twice and casts arguments as any[] rather than inferring them from the original function (though I'm not sure if facebook flow does support actually that).

I'm not aware of such support. The best I can think of is having this - I'm in favor of adding this if you agree because it's more accurate.

declare export function flow<T>(
    fn: () => Generator<any, T | Promise<T>, any>
): () => CancellablePromise<T>

declare export function flow<T, A>(
    fn: (A) => Generator<any, T | Promise<T>, any>
): (A) => CancellablePromise<T>

declare export function flow<T, A, B>(
    fn: (A, B) => Generator<any, T | Promise<T>, any>
): (A, B) => CancellablePromise<T>

// and so on, until let's, say 4 params?

Shame, that seems like a good workaround (that's how it used to be in TS actually before they added support for that). I'd make it 8-10 args though.

Also in TS R | Promise is not required in TS, but again I'm not an expert of facebook flow.

this is required in Flow

Ahh shame. What about

Generator<any, T | Promise<T>, any> | AsyncGenerator<any, T | Promise<T>, any>

is that supported?

@vonovak
Copy link
Contributor Author

vonovak commented Oct 22, 2019

Also in TS R | Promise is not required in TS, but again I'm not an expert of facebook flow.

why is that a shame? I mean, returning T or Promise are two different things, so Flow makes a distinction there.

the PR should be good for merge now

@xaviergonz
Copy link
Contributor

LGTM, just to make sure, arg names are not required in flow, just the types?

@vonovak
Copy link
Contributor Author

vonovak commented Oct 22, 2019

arg names are not required in flow, just the types?

yes, I tested this locally and it is working fine

@danielkcz danielkcz merged commit b3d2c84 into mobxjs:master Oct 22, 2019
@danielkcz
Copy link
Contributor

What about MobX4, does it need same tweaks?

@vonovak
Copy link
Contributor Author

vonovak commented Oct 22, 2019

@FredyC this feature works the same there afaik, so no

@vonovak vonovak deleted the patch-1 branch October 22, 2019 19:38
@danielkcz
Copy link
Contributor

danielkcz commented Oct 22, 2019

@vonovak Wait, so in MobX4 the types were already fixed in the past? Or what do you mean by that? Can you verify it, please?

@vonovak
Copy link
Contributor Author

vonovak commented Oct 22, 2019

sorry, I misunderstood your comment, yes, you should cherry pick this for mobx 4 as well. When do you think this will go public?

@danielkcz
Copy link
Contributor

@vonovak Well, I don't really understand what's going on here. Can you cherry-pick, please? :) We certainly won't publish till both branches are in sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants