architect / functions

AWS Lambda Node runtime helpers for Architect apps
https://arc.codes
163 stars 38 forks source link

v7 types update #551

Closed tbeseda closed 1 year ago

tbeseda commented 1 year ago

alternative to https://github.com/architect/functions/pull/550

Typings for new Architect Functions v7 features as well as some minor fixes for missing features in HTTPRequests and "middleware" return types.

still todo:

comment on .d.ts vs JSDoc:

Unfortunately, I don't think the JSDoc approach for a consumed library with complex types is sustainable right now. The TS lang server (used by most modern editors to parse Javascript files) is inconsistent in how it interprets doc comments and bubbles those types to the end user/developer working with Arc.

So for now, I still recommend keeping a types/ dir with exported types written in TS and tested with a simple .test-d.ts file.

tbeseda commented 1 year ago

While the arc.http() overload is a welcome change it did make type declarations a little tricky since the method signature is the same: n number of handlers. Here's a rundown of the only caveat when using async handlers

import arc from "@architect/functions";
import type { HttpAsyncHandler } from "@architect/functions";

// Some logging middlewares
function middleware (req, _res, next) {
  console.log(req.method, req.path);
  next();
};
// ... and async version cast as HttpAsyncHandler
const asyncMiddleware: HttpAsyncHandler = async (req, _ctx) => {
  console.log(req.method, req.path);
  // resolution happens automatically
}

// default callback pattern
arc.http(function (_req, res) {
  return res({ json: { types: true } });
});

// with middleware
arc.http(middleware, function (_req, res) {
  return res({ json: { types: true } });
});

// async pattern
arc.http(async function (_req, _ctx) {
  // await something
  return { html: "<h1>types</h1>" };
} as HttpAsyncHandler);

// with async middleware
arc.http(asyncMiddleware, <HttpAsyncHandler>async function (_req, _ctx) {
  return { text: "types" };
});

Note that the anonymous async handlers and middleware can be cast as HttpAsyncHandler in a few ways