Skip to content

Commit 6a22b1f

Browse files
fix(types): ensure nextTick return type reflect correct Promise value (#8406)
1 parent 438027c commit 6a22b1f

File tree

3 files changed

+25
-4
lines changed

3 files changed

+25
-4
lines changed

packages/runtime-core/__tests__/scheduler.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,4 +546,16 @@ describe('scheduler', () => {
546546
await nextTick()
547547
expect(spy).toHaveBeenCalledTimes(1)
548548
})
549+
550+
it('nextTick should return promise', async () => {
551+
const fn = vi.fn(() => {
552+
return 1
553+
})
554+
555+
const p = nextTick(fn)
556+
557+
expect(p).toBeInstanceOf(Promise)
558+
expect(await p).toBe(1)
559+
expect(fn).toHaveBeenCalledTimes(1)
560+
})
549561
})

packages/runtime-core/src/scheduler.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ErrorCodes, callWithErrorHandling } from './errorHandling'
2-
import { isArray, NOOP } from '@vue/shared'
2+
import { Awaited, isArray, NOOP } from '@vue/shared'
33
import { ComponentInternalInstance, getComponentName } from './component'
44
import { warn } from './warning'
55

@@ -50,10 +50,10 @@ let currentFlushPromise: Promise<void> | null = null
5050
const RECURSION_LIMIT = 100
5151
type CountMap = Map<SchedulerJob, number>
5252

53-
export function nextTick<T = void>(
53+
export function nextTick<T = void, R = void>(
5454
this: T,
55-
fn?: (this: T) => void
56-
): Promise<void> {
55+
fn?: (this: T) => R
56+
): Promise<Awaited<R>> {
5757
const p = currentFlushPromise || resolvedPromise
5858
return fn ? p.then(this ? fn.bind(this) : fn) : p
5959
}

packages/shared/src/typeUtils.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,12 @@ export type LooseRequired<T> = { [P in keyof (T & Required<T>)]: T[P] }
1212
// If the type T accepts type "any", output type Y, otherwise output type N.
1313
// https://stackoverflow.com/questions/49927523/disallow-call-with-any/49928360#49928360
1414
export type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N
15+
16+
// To prevent users with TypeScript versions lower than 4.5 from encountering unsupported Awaited<T> type, a copy has been made here.
17+
export type Awaited<T> = T extends null | undefined
18+
? T // special case for `null | undefined` when not in `--strictNullChecks` mode
19+
: T extends object & { then(onfulfilled: infer F, ...args: infer _): any } // `await` only unwraps object types with a callable `then`. Non-object types are not unwrapped
20+
? F extends (value: infer V, ...args: infer _) => any // if the argument to `then` is callable, extracts the first argument
21+
? Awaited<V> // recursively unwrap the value
22+
: never // the argument to `then` was not callable
23+
: T // non-object or non-thenable

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy