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 mobx4 [requires TS3.6, mobx4] #2161

Merged
merged 2 commits into from
Nov 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,4 @@
"pre-commit": "lint-staged"
}
}
}
}
36 changes: 6 additions & 30 deletions src/api/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,9 @@ let generatorId = 0

export type CancellablePromise<T> = Promise<T> & { cancel(): void }

export interface FlowYield {
// fake, only for typing
"!!flowYield": undefined
}

export interface FlowReturn<T> {
// fake, only for typing
"!!flowReturn": T
}

// we skip promises that are the result of yielding promises (except if they use flowReturn)
export type FlowReturnType<R> = IfAllAreFlowYieldThenVoid<
R extends FlowReturn<infer FR>
? FR extends Promise<infer FRP>
? FRP
: FR
: R extends Promise<any>
? FlowYield
: R
>

// we extract yielded promises from the return type
export type IfAllAreFlowYieldThenVoid<R> = Exclude<R, FlowYield> extends never
? void
: Exclude<R, FlowYield>

export function flow<R, Args extends any[]>(
generator: (...args: Args) => IterableIterator<R>
): (...args: Args) => CancellablePromise<FlowReturnType<R>> {
generator: (...args: Args) => Generator<any, R, any> | AsyncGenerator<any, R, any>
): (...args: Args) => CancellablePromise<R> {
if (arguments.length !== 1)
fail(
!!process.env.NODE_ENV && `Flow expects one 1 argument and cannot be used as decorator`
Expand All @@ -44,7 +18,9 @@ export function flow<R, Args extends any[]>(
const ctx = this
const args = arguments
const runId = ++generatorId
const gen = action(`${name} - runid: ${runId} - init`, generator).apply(ctx, args)
const gen = action(`${name} - runid: ${runId} - init`, generator as (
...args: Args
) => Generator<any, R, any>).apply(ctx, args)
let rejector: (error: any) => void
let pendingPromise: CancellablePromise<any> | undefined = undefined

Expand Down Expand Up @@ -110,7 +86,7 @@ export function flow<R, Args extends any[]>(
rejector(e) // there could be a throwing finally block
}
})
return (res as CancellablePromise<R>) as any
return res as CancellablePromise<R>
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/types/observablemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export class ObservableMap<K = any, V = any>
return makeIterable({
next() {
return nextIndex < self._keys.length
? { value: self.get(self._keys[nextIndex++]), done: false }
? { value: self.get(self._keys[nextIndex++])!, done: false }
: { value: undefined as any, done: true }
}
})
Expand Down
19 changes: 15 additions & 4 deletions test/base/typescript-tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand Down Expand Up @@ -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
Expand All @@ -1615,7 +1615,7 @@ test("flow support throwing async generators", async () => {
total += number
}
return total
} as any) // TODO: fix typings
})

const p = start()
try {
Expand Down Expand Up @@ -1647,3 +1647,14 @@ 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)
})
12 changes: 6 additions & 6 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7945,9 +7945,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"
Expand Down Expand Up @@ -7994,9 +7994,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"
Expand Down