Skip to content

feat: types for express 5#70563

Merged
typescript-bot merged 29 commits intoDefinitelyTyped:masterfrom
RobinTail:feat-async-for-express5
Sep 25, 2024
Merged

feat: types for express 5#70563
typescript-bot merged 29 commits intoDefinitelyTyped:masterfrom
RobinTail:feat-async-for-express5

Conversation

@RobinTail
Copy link
Copy Markdown
Contributor

@RobinTail RobinTail commented Sep 14, 2024

Alternative to #69846 (comment) — the author is sick and can not continue.

The primary goal of this PR is to release the types for express version 5 — the main difference is allowing Promise<void> along with void on RequestHandler.

Challenge: void was technically compatible with anything actually returned, but void | Promise<void> is not.

Tracked in: expressjs/express#5944


Please fill in this template.

Select one of these and delete the others:

If adding a new definition:

  • The package does not already provide its own types, or cannot have its .d.ts files generated via --declaration
  • If this is for an npm package, match the name. If not, do not conflict with the name of an npm package.
  • Create it with dts-gen --dt, not by basing it on an existing project.
  • Represents shape of module/library correctly
  • tsconfig.json should have noImplicitAny, noImplicitThis, strictNullChecks, and strictFunctionTypes set to true.

If changing an existing definition:

If removing a declaration:

  • If a package was never on Definitely Typed, you don't need to do anything. (If you wrote a package and provided types, you don't need to register it with us.)
  • Delete the package's directory.
  • Add it to notNeededPackages.json.

Comment thread types/express-ua-middleware/index.d.ts
Comment thread types/express-brute/index.d.ts
Comment thread types/absolute-url/package.json
Comment thread types/feathersjs__express/feathersjs__express-tests.ts
Comment thread types/express-oauth-server/index.d.ts
@RobinTail
Copy link
Copy Markdown
Contributor Author

RobinTail commented Sep 14, 2024

✅ All tests pass now.

  • some packages have mistakes is tests
  • some packages have wrong types
  • some packages have discrepancies in the declared dependencies
  • some declare express compatibility as * which is probably not true, and really implies ^4, but...

I'm requesting comments and I'm open for advises and suggestions on how this important change could be made even better and released faster.

@RobinTail RobinTail marked this pull request as ready for review September 14, 2024 11:14
@typescript-bot
Copy link
Copy Markdown
Contributor

typescript-bot commented Sep 14, 2024

@RobinTail Thank you for submitting this PR!

This is a live comment that I will keep updated.

This PR touches some part of DefinitelyTyped infrastructure, so a DT maintainer will need to review it. This is rare — did you mean to do this?

16 packages in this PR (and infra files)

Code Reviews

Because this is a widely-used package, a DT maintainer will need to review it before it can be merged.

You can test the changes of this PR in the Playground.

Status

  • ✅ No merge conflicts
  • ✅ Continuous integration tests have passed
  • ✅ A DT maintainer needs to approve changes that affect DT infrastructure (attw.json)

All of the items on the list are green. To merge, you need to post a comment including the string "Ready to merge" to bring in your changes.


Diagnostic Information: What the bot saw about this PR
{
  "type": "info",
  "now": "-",
  "pr_number": 70563,
  "author": "RobinTail",
  "headCommitOid": "8f3a52d98bbbe1539d19bda7cc63581c241d4d9b",
  "mergeBaseOid": "b0208c9d870b7bfa747d7ed9c7c108c95207cc97",
  "lastPushDate": "2024-09-14T08:37:10.000Z",
  "lastActivityDate": "2024-09-25T19:08:01.000Z",
  "mergeOfferDate": "2024-09-25T17:37:04.000Z",
  "mergeRequestDate": "2024-09-25T19:08:01.000Z",
  "mergeRequestUser": "RobinTail",
  "hasMergeConflict": false,
  "isFirstContribution": false,
  "tooManyFiles": false,
  "hugeChange": false,
  "popularityLevel": "Critical",
  "pkgInfo": [
    {
      "name": null,
      "kind": "edit",
      "files": [
        {
          "path": "attw.json",
          "kind": "infrastructure"
        }
      ],
      "owners": [],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Critical",
      "isSafeInfrastructureEdit": false
    },
    {
      "name": "absolute-url",
      "kind": "edit",
      "files": [
        {
          "path": "types/absolute-url/package.json",
          "kind": "package-meta-ok"
        }
      ],
      "owners": [
        "tpluscode",
        "ludovicm67"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "architect__functions",
      "kind": "edit",
      "files": [
        {
          "path": "types/architect__functions/test/http-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "activescott",
        "ryanblock",
        "reconbot"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "create-test-server",
      "kind": "edit",
      "files": [
        {
          "path": "types/create-test-server/index.d.ts",
          "kind": "definition"
        }
      ],
      "owners": [
        "midgleyc"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "express-brute",
      "kind": "edit",
      "files": [
        {
          "path": "types/express-brute/index.d.ts",
          "kind": "definition"
        }
      ],
      "owners": [
        "cyrilschumacher"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "express-oauth-server",
      "kind": "edit",
      "files": [
        {
          "path": "types/express-oauth-server/express-oauth-server-tests.ts",
          "kind": "test"
        },
        {
          "path": "types/express-oauth-server/index.d.ts",
          "kind": "definition"
        }
      ],
      "owners": [
        "atd-schubert"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "express-serve-static-core",
      "kind": "edit",
      "files": [
        {
          "path": "types/express-serve-static-core/.npmignore",
          "kind": "package-meta-ok"
        },
        {
          "path": "types/express-serve-static-core/express-serve-static-core-tests.ts",
          "kind": "test"
        },
        {
          "path": "types/express-serve-static-core/index.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/express-serve-static-core/package.json",
          "kind": "package-meta-ok"
        },
        {
          "path": "types/express-serve-static-core/v4/.eslintrc.json",
          "kind": "package-meta",
          "suspect": "edited"
        },
        {
          "path": "types/express-serve-static-core/v4/.npmignore",
          "kind": "package-meta-ok"
        },
        {
          "path": "types/express-serve-static-core/v4/express-serve-static-core-tests.ts",
          "kind": "test"
        },
        {
          "path": "types/express-serve-static-core/v4/index.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/express-serve-static-core/v4/package.json",
          "kind": "package-meta-ok"
        },
        {
          "path": "types/express-serve-static-core/v4/tsconfig.json",
          "kind": "package-meta-ok"
        }
      ],
      "owners": [
        "borisyankov",
        "micksatana",
        "JoseLion",
        "dwrss",
        "andoshin11"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Critical"
    },
    {
      "name": "express-ua-middleware",
      "kind": "edit",
      "files": [
        {
          "path": "types/express-ua-middleware/index.d.ts",
          "kind": "definition"
        }
      ],
      "owners": [
        "peterblazejewicz"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "express",
      "kind": "edit",
      "files": [
        {
          "path": "types/express/.npmignore",
          "kind": "package-meta-ok"
        },
        {
          "path": "types/express/express-tests.ts",
          "kind": "test"
        },
        {
          "path": "types/express/package.json",
          "kind": "package-meta-ok"
        },
        {
          "path": "types/express/v4/.eslintrc.json",
          "kind": "package-meta",
          "suspect": "edited"
        },
        {
          "path": "types/express/v4/.npmignore",
          "kind": "package-meta-ok"
        },
        {
          "path": "types/express/v4/express-tests.ts",
          "kind": "test"
        },
        {
          "path": "types/express/v4/index.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/express/v4/package.json",
          "kind": "package-meta-ok"
        },
        {
          "path": "types/express/v4/tsconfig.json",
          "kind": "package-meta-ok"
        }
      ],
      "owners": [
        "borisyankov",
        "CMUH",
        "puneetar",
        "dfrankland"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Critical"
    },
    {
      "name": "feathersjs__express",
      "kind": "edit",
      "files": [
        {
          "path": "types/feathersjs__express/feathersjs__express-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "j2L4e",
        "DadUndead"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "forest-express-mongoose",
      "kind": "edit",
      "files": [
        {
          "path": "types/forest-express-mongoose/forest-express-mongoose-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "SteveBunlon",
        "ghusse"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "forest-express-sequelize",
      "kind": "edit",
      "files": [
        {
          "path": "types/forest-express-sequelize/forest-express-sequelize-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "SteveBunlon",
        "ghusse"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "fusebit__oauth-connector",
      "kind": "edit",
      "files": [
        {
          "path": "types/fusebit__oauth-connector/fusebit__oauth-connector-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "andrewrmiller",
        "hashiphoto",
        "andydam"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "logfmt",
      "kind": "edit",
      "files": [
        {
          "path": "types/logfmt/logfmt-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "ebroder"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "mock-req-res",
      "kind": "edit",
      "files": [
        {
          "path": "types/mock-req-res/mock-req-res-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "sandorTuranszky"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "mongoose-aggregate-paginate-v2",
      "kind": "edit",
      "files": [
        {
          "path": "types/mongoose-aggregate-paginate-v2/mongoose-aggregate-paginate-v2-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "acrilex1"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    },
    {
      "name": "swaggerize-express",
      "kind": "edit",
      "files": [
        {
          "path": "types/swaggerize-express/swaggerize-express-tests.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "mugeso",
        "nickmorton"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Well-liked by everyone"
    }
  ],
  "reviews": [
    {
      "type": "approved",
      "reviewer": "jakebailey",
      "date": "2024-09-25T17:36:23.000Z",
      "isMaintainer": true
    },
    {
      "type": "stale",
      "reviewer": "ludovicm67",
      "date": "2024-09-23T11:46:42.000Z",
      "abbrOid": "635727b"
    },
    {
      "type": "stale",
      "reviewer": "midgleyc",
      "date": "2024-09-23T10:44:45.000Z",
      "abbrOid": "635727b"
    },
    {
      "type": "stale",
      "reviewer": "tpluscode",
      "date": "2024-09-16T12:34:58.000Z",
      "abbrOid": "635727b"
    }
  ],
  "mainBotCommentID": 2350955911,
  "ciResult": "pass"
}

@typescript-bot
Copy link
Copy Markdown
Contributor

@AviVahl
Copy link
Copy Markdown
Contributor

AviVahl commented Sep 26, 2024

the rule is only included in configs.recommendedTypeChecked, which also requires one to specify additional settings (such as projectService or project, etc.)

I realize I can disable lint for that line/file, cast the type, or disable rule. The thing is... I believe the rule is correct. The express handler possibly returns a Promise (according to the type), and node http handler doesn't handle promises. Just an FYI, since it might be a common use-case to use the app itself as handler for a native http server.

Not sure I want to tackle this on my own. I'll probably just workaround in user-end.

@davps
Copy link
Copy Markdown

davps commented Oct 23, 2024

There seems to be a version management discrepancy. While @types/express has already moved to v5 (via #70563), npm outdated still considers Express 4.21.1 as the "latest" version:

Current package.json:

{
  "dependencies": {
    "express": "^5.0.1"
  },
  "devDependencies": {
    "@types/express": "^5.0.0"
  }
}

Running npm outdated shows:

Package   Current  Wanted  Latest   Location              Depended by
express   5.0.1    5.0.1   4.21.1  node_modules/express  [project-name]

This creates potential confusion since:

  1. The types have officially moved to v5
  2. Users running npm outdated might think they need to downgrade to 4.21.1. This is my case, I ran into this in my CI/CD.

@jakebailey
Copy link
Copy Markdown
Member

That was an intentional choice made by the express maintainers; v5 is not marked as latest over there.

DefinitelyTyped has no mechanism to model this somewhat unusual situation.

@davps
Copy link
Copy Markdown

davps commented Oct 23, 2024

I see, thanks for the clarification @jakebailey

I'll just disable npm outdated for now in my CI/CD since this mismatch happens in both directions - whether using Express v4 with types v4, or Express v5 with types v5, npm outdated always shows version conflicts. I'm sure it will sort itself out as v5 adoption grows. Thanks.

alino20 pushed a commit to alino20/DefinitelyTyped that referenced this pull request Dec 31, 2024
@binarykitchen
Copy link
Copy Markdown

Not sure I want to tackle this on my own. I'll probably just workaround in user-end.

@AviVahl Have you figured out a workaround yet?

(Experiencing the same issue here)

@AviVahl
Copy link
Copy Markdown
Contributor

AviVahl commented Feb 23, 2025

Not sure I want to tackle this on my own. I'll probably just workaround in user-end.

@AviVahl Have you figured out a workaround yet?

(Experiencing the same issue here)

use a cast:

import { createServer, type RequestListener } from "node:http";
import express from "express";

const app = express();
const httpServer = createServer(app as RequestListener);

or use @types/[email protected] (latest 4.x types; npm info @types/express versions), if you're still using express@4.

@binarykitchen
Copy link
Copy Markdown

Thanks, @AviVahl, I'll do this for now, temporarily. Using express@5 here.

Although, force casting should be avoided. Wondering if this has every been raised upstream before and will ever be fixed?

@glasser
Copy link
Copy Markdown
Contributor

glasser commented May 8, 2025

I ran into the same issue with ESLint configs.recommendedTypeChecked and createServer(app) as @AviVahl. I'll try the as RequestListener workaround, but it is an interesting point that if the app can return a Promise and http.createServer doesn't handle that, it could be a problem? The official Express docs do still teach http.createServer(app) as a reasonable thing to do.

Copy link
Copy Markdown

@robertomiramon50-stack robertomiramon50-stack left a comment

Choose a reason for hiding this comment

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

__

marmitar added a commit to marmitar/thelounge that referenced this pull request Jan 31, 2026
marmitar added a commit to marmitar/thelounge that referenced this pull request Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Check Config Changes a module config files Critical package Edits Infrastructure Edits multiple packages Maintainer Approved Self Merge This PR can now be self-merged by the PR author or an owner

Projects

None yet

Development

Successfully merging this pull request may close these issues.