From 728ad70feef5856060e1dd30516ca1c6161803dd Mon Sep 17 00:00:00 2001 From: Javier Gonzalez Date: Thu, 7 Nov 2019 21:41:15 +0100 Subject: [PATCH] Fix flow typings [requires TS3.6] (#2160) * fix for flow typings * undo changelog formatting * put proper set type * fix async generator typing in flows --- CHANGELOG.md | 3 ++- src/api/flow.ts | 41 ++++++----------------------------- src/core/computedvalue.ts | 2 +- test/base/typescript-tests.ts | 20 +++++++++++++---- yarn.lock | 12 +++++----- 5 files changed, 32 insertions(+), 46 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bcc7b73b9..2e2297bda 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ -- cancelled flows now reject with a `FlowCancellationError` instance whose error message is the same as in previous versions (`"FLOW_CANCELLED"`) so this is not breaking. +- Fixed flow typings with Typescript v3.6. This means that version of Typescript is required when using flows. +- Cancelled flows now reject with a `FlowCancellationError` instance whose error message is the same as in previous versions (`"FLOW_CANCELLED"`) so this is not breaking. - Fix running mobx in web worker [#2184](https://github.com/mobxjs/mobx/pull/2184/files) - Fixed flow typings for Facebook's Flow. A new `CancellablePromise` Flow type is exported. diff --git a/src/api/flow.ts b/src/api/flow.ts index 0cb27e7ce..d1a915d32 100644 --- a/src/api/flow.ts +++ b/src/api/flow.ts @@ -14,35 +14,9 @@ export function isFlowCancellationError(error: Error) { export type CancellablePromise = Promise & { cancel(): void } -export interface FlowYield { - // fake, only for typing - "!!flowYield": undefined -} - -export interface FlowReturn { - // fake, only for typing - "!!flowReturn": T -} - -// we skip promises that are the result of yielding promises (except if they use flowReturn) -export type FlowReturnType = IfAllAreFlowYieldThenVoid< - R extends FlowReturn - ? FR extends Promise - ? FRP - : FR - : R extends Promise - ? FlowYield - : R -> - -// we extract yielded promises from the return type -export type IfAllAreFlowYieldThenVoid = Exclude extends never - ? void - : Exclude - export function flow( - generator: (...args: Args) => IterableIterator -): (...args: Args) => CancellablePromise> { + generator: (...args: Args) => Generator | AsyncGenerator +): (...args: Args) => CancellablePromise { if (arguments.length !== 1) fail(!!process.env.NODE_ENV && `Flow expects 1 argument and cannot be used as decorator`) const name = generator.name || "" @@ -52,10 +26,9 @@ export function flow( const ctx = this const args = arguments const runId = ++generatorId - const gen = action(`${name} - runid: ${runId} - init`, generator).apply( - ctx, - (args as any) as Args - ) + const gen = action(`${name} - runid: ${runId} - init`, generator as ( + ...args: Args + ) => Generator).apply(ctx, (args as any) as Args) let rejector: (error: any) => void let pendingPromise: CancellablePromise | undefined = undefined @@ -110,7 +83,7 @@ export function flow( try { if (pendingPromise) cancelPromise(pendingPromise) // Finally block can return (or yield) stuff.. - const res = gen.return!() + const res = gen.return!(undefined as any) // eat anything that promise would do, it's cancelled! const yieldedPromise = Promise.resolve(res.value) yieldedPromise.then(noop, noop) @@ -121,7 +94,7 @@ export function flow( rejector(e) // there could be a throwing finally block } }) - return promise as CancellablePromise> + return promise as CancellablePromise } } diff --git a/src/core/computedvalue.ts b/src/core/computedvalue.ts index e9b2bd9d7..fd3e96bde 100644 --- a/src/core/computedvalue.ts +++ b/src/core/computedvalue.ts @@ -72,7 +72,7 @@ export class ComputedValue implements IObservable, IComputedValue, IDeriva newObserving = null // during tracking it's an array with new observed observers isBeingObserved = false isPendingUnobservation: boolean = false - observers = new Set() + observers = new Set() diffValue = 0 runId = 0 lastAccessedBy = 0 diff --git a/test/base/typescript-tests.ts b/test/base/typescript-tests.ts index 609e8e51c..04bbc1530 100644 --- a/test/base/typescript-tests.ts +++ b/test/base/typescript-tests.ts @@ -1557,9 +1557,9 @@ test("it should support asyncAction as decorator (ts)", async () => { class X { @observable a = 1 - f = mobx.flow(function* f(initial: number): any { + f = mobx.flow(function* f(this: X, initial: number) { this.a = initial // this runs in action - this.a += yield Promise.resolve(5) + this.a += yield Promise.resolve(5) as any this.a = this.a * 2 return this.a }) @@ -1590,7 +1590,7 @@ test("flow support async generators", async () => { total += number } return total - } as any) // TODO: fix typings + }) const p = start() const res = await p @@ -1615,7 +1615,7 @@ test("flow support throwing async generators", async () => { total += number } return total - } as any) // TODO: fix typings + }) const p = start() try { @@ -1648,6 +1648,18 @@ test("verify #1528", () => { expect(appState.timer).toBe(0) }) +test("type of flows that return promises", async () => { + mobx.configure({ enforceActions: "observed" }) + + const f = mobx.flow(function* f() { + return Promise.resolve(5) + }) + + const n: number = await f() + expect(n).toBe(5) + +}) + test("#2159 - computed property keys", () => { const testSymbol = Symbol("test symbol") const testString = "testString" diff --git a/yarn.lock b/yarn.lock index b75206e0a..8c523da27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8114,9 +8114,9 @@ ts-jest@^24.0.0: yargs-parser "10.x" tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: - version "1.9.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== tsutils@^3.7.0: version "3.10.0" @@ -8173,9 +8173,9 @@ typedarray@^0.0.6: integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= typescript@^3.3.3333: - version "3.4.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.4.4.tgz#aac4a08abecab8091a75f10842ffa0631818f785" - integrity sha512-xt5RsIRCEaf6+j9AyOBgvVuAec0i92rgCaS3S+UVf5Z/vF2Hvtsw08wtUTJqp4djwznoAgjSxeCcU4r+CcDBJA== + version "3.6.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.6.4.tgz#b18752bb3792bc1a0281335f7f6ebf1bbfc5b91d" + integrity sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg== uglify-js@^3.1.4: version "3.5.5"