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

[Typescript] Improving flow typings #1378 #1409

Merged
merged 1 commit into from
Oct 31, 2019
Merged

[Typescript] Improving flow typings #1378 #1409

merged 1 commit into from
Oct 31, 2019

Conversation

nulladdict
Copy link
Contributor

@nulladdict nulladdict commented Oct 28, 2019

This is an attempt to fix #1378

This is a breaking change to flow typings that requires TS version 3.6+
I am still not sold on the final solution, but I see two major alternatives:

  • the one described in this comment and implemented in this PR
  • typing flow as Generator<Promise<any>, R, unknown>, so that we get inferred return type, type-check on yielded promises and that we're required to type yield results, which is somewhat similar to what we had before

Both of this are not perfect and still breaking, because TS changed Generator interface.
It seems that there's a possibility to escape the breaking change by utilising typesVersions as mentioned here, however I am not quite sure I understand how to do that

It is also worth mentioning that with arriving of actionAsync this problem might not be that important, and we might just use the second alternative to fix TS errors and not rely on lots of TS magic

@xaviergonz
Copy link
Contributor

flow typings should be fixed (when using ts3.6) with version 3.15.0 that was just released, give it a try :)

@nulladdict
Copy link
Contributor Author

3.15.0 looks good, however I believe it introduces a type regression when returning a Promise:

const f = flow(function*() {
  yield promise
  return Promise.resolve(2)
})
// f is () => Promise<Promise<number>>
const x = await f() // x is correctly inferred as number
f().then(x => { /* ... */ }) // x is Promise<number> when in fact it's just a number

taking a look at flow return code:

wrap((r: any) => { resolve(r) }, "flow_return", ret.value)

resolve(r) when r is a promise would produce a Promise<T> and not a nested one, so the correct return type in our example is Promise<number>, await just hides the issue

I've fixed this and added a test for this specific case
Also I've change yielded type from any to Promise<any> since we don't support any other yielded values anyway

@nulladdict nulladdict marked this pull request as ready for review October 30, 2019 08:33
* Fix nesting promise when returning
* Add nesting return test
* Allow only Promise types to be yielded
@nulladdict nulladdict changed the title [Typescript] Attempt to fix flow typings #1378 [Typescript] Improving flow typings #1378 Oct 30, 2019
@xaviergonz
Copy link
Contributor

xaviergonz commented Oct 30, 2019

Technically I think then will also resolve to a number even when taking Promise<Promise<number>>, so that shouldn't matter much, but I guess it is better to keep API typing compatibility.

Also forcing yield to take promises should help catching bugs, so LGTM 😁

@nulladdict
Copy link
Contributor Author

You’re absolutely right, it would resolve to a number, but typescript would complain, so yeah, it’s just for compatibility

@mweststrate mweststrate merged commit 129e0be into mobxjs:master Oct 31, 2019
@nulladdict nulladdict deleted the flow-inference branch October 31, 2019 13:55
@mweststrate
Copy link
Member

Released in 3.16. Apologies for the late follow up!

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.

[TypeScript 3.6+] flow() | Inferred Generator type is not assignable to IterableIterator
3 participants