Skip to content

Use Awaited type to avoid Promise<Promise<T>>#68

Merged
chodorowicz merged 7 commits intochodorowicz:mainfrom
urbanfly:feature/awaited
Apr 11, 2026
Merged

Use Awaited type to avoid Promise<Promise<T>>#68
chodorowicz merged 7 commits intochodorowicz:mainfrom
urbanfly:feature/awaited

Conversation

@urbanfly
Copy link
Copy Markdown
Contributor

@urbanfly urbanfly commented Dec 5, 2024

When debouncing a Promise-returning function, the returned function has a type of Promise<Promise<T>> which is not accurate - see microsoft/TypeScript#27711

In TypeScript 4.5, a new Awaited<T> type was introduced to solve this problem.

This PR simply wraps the ReturnType<F> with Awaited<...> in order to get an accurate return type for the created function.

Several packages were updated:

  • Typescript bumped to 4.5 in order to access this type
  • microbundle in order to build
  • jest / ts-jest in order to test with this type
  • tsd in order to validate the types

@urbanfly urbanfly changed the title Use Awaited type to avoide Promise<Promise<T>> Use Awaited type to avoid Promise<Promise<T>> Dec 5, 2024
@chodorowicz
Copy link
Copy Markdown
Owner

Hey @urbanfly
Sorry for the absurdly long delay with replying 🙇

The change makes sense, thanks. There's one issue though, the type for the callback functions Options<Awaited<ReturnType<F>>> doesn't match the existing behavior as the promises there are not flattened with resolve and result is passed directly to the callback function. I've added tests that document that behavior → https://github.com/chodorowicz/ts-debounce/pull/70/changes

if you're still around and interested in merging this change, I'm happy to do it after this issue is fixed.

@urbanfly
Copy link
Copy Markdown
Contributor Author

urbanfly commented Apr 6, 2026

I didn't originally get your point about the callback/options. I have removed Awaited from the options argument.

@chodorowicz
Copy link
Copy Markdown
Owner

chodorowicz commented Apr 6, 2026

Thanks, looks good!

There's conflict with the base branch, which needs to get resolved first (both merge and rebase are fine)
Also, type test have issue

  ✖  34:0  Parameter type () => Promise<number> is declared too wide for argument type DebouncedFunction<[], () => Promise<number>>.

expectType requires strict type equality. using expectAssignable from tsd should be good to solve the problem.

Happy to merge this after resolving this two issue.

@urbanfly
Copy link
Copy Markdown
Contributor Author

urbanfly commented Apr 7, 2026

I've rebased and tried to run the tests. The Jest tests pass, but test:types fails on tsd:

The type definition dist/src/index.d.ts does not exist at /workspaces/ts-debounce/dist/src/index.d.ts. Is the path correct? Create one and try again.

It seems like it depends on the build script to run first, but that also fails:

image

Add @babel/preset-flow to the presets section of your Babel config to enable transformation.
If you want to leave it as-is, add @babel/plugin-syntax-flow to the 'plugins' section to enable parsing.

If you already added the plugin for this syntax to your config, it's possible that your config isn't being loaded.
You can re-run Babel with the BABEL_SHOW_CONFIG_FOR environment variable to show the loaded configuration:

npx cross-env BABEL_SHOW_CONFIG_FOR=/workspaces/ts-debounce/src/index.ts <your build command>

See https://babeljs.io/docs/configuration#print-effective-configs for more info.

I was able to work-around it locally by removing the --noEmit flag from tsc so that the dist folder gets populated (and then adjust the paths for types in package.json to match the expectation). So at this point, npm run test passes, but only with some uncommitted work-arounds.

@chodorowicz chodorowicz requested a review from Copilot April 7, 2026 21:31
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the TypeScript typings for debounce so that debouncing a Promise-returning function yields Promise<T> instead of Promise<Promise<T>>, leveraging TypeScript 4.5’s Awaited<T> utility type.

Changes:

  • Update DebouncedFunction/internal Promise generics to use Awaited<ReturnType<F>> for the debounced return type.
  • Add a tsd assertion to ensure the debounced function type is assignable to () => Promise<number> for async functions.
  • Bump tooling dependencies (TypeScript, Jest, ts-jest, microbundle, tsd) to versions compatible with Awaited.

Reviewed changes

Copilot reviewed 3 out of 5 changed files in this pull request and generated 3 comments.

File Description
src/index.ts Uses Awaited<ReturnType<F>> to prevent Promise<Promise<T>> in debounced return types.
src/index.test-d.ts Adds type-level assertions verifying the debounced return type is a single Promise.
package.json Updates dev tooling versions to support Awaited and related build/test tooling.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/index.ts
Comment thread src/index.ts
Comment thread package.json Outdated
@chodorowicz
Copy link
Copy Markdown
Owner

The CI job, which includes pnpm run test:types, is green.

The last thing is to remove package-lock.json from the PR, as this project uses pnpm and pnpm-lock.yaml.

Copy link
Copy Markdown
Contributor Author

@urbanfly urbanfly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how I "Started a review". I just replied to Copilots's comment re: @types/jest version within VS Code.

@urbanfly
Copy link
Copy Markdown
Contributor Author

urbanfly commented Apr 9, 2026

I saw the build failure and have now properly installed @types/jest to v29 so that the pnpm-lock.json file is updated correctly.

Updating to Jest v29 made useFakeTimes("modern") fail, so removed the parameter. See https://jest-archive-august-2023.netlify.app/docs/28.x/upgrading-to-jest28/#jestusefaketimers

@chodorowicz chodorowicz merged commit 8bf4d1e into chodorowicz:main Apr 11, 2026
1 check passed
@chodorowicz
Copy link
Copy Markdown
Owner

@all-contributors add @urbanfly for code

@allcontributors
Copy link
Copy Markdown
Contributor

@chodorowicz

I've put up a pull request to add @urbanfly! 🎉

@chodorowicz
Copy link
Copy Markdown
Owner

Thanks for your contribution @urbanfly 🙇

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.

3 participants