Add explicit type safety to `compose` utility
- Dominant language
- TypeScript
- Stars
- 1.7k
- Forks
- 41
- PR merge metrics
- No merged PRs in 30d
Description
As of #23, the `compose` export now exists. However, it only has basic `req.params` value forwarding.
This issue remains open so that `compose` can (*_should_) guard against `Handler`s that are loaded before their required properties have been satisfied.
For example:
```ts
import { compose } from 'worktop';
import type { Handler } from 'worktop';
import type { ServerRequest } from 'worktop/request';
import type { User, App } from 'lib/models';
type UserRequest = ServerRequest & { user: User };
type AppRequest = ServerRequest & { app: App };
// Assume it reads `Authorization` header, and loads `req.user` or bails
// ~> only "needs" a bare `ServerRequest`, provides a `UserRequest`
// HINT: Read the type argument left-to-right for Request mutation
declare const toUser: Handler;
// Assume it reads loads the relevant `App` record
// ~> only "needs" a bare `ServerRequest`, provides a `AppRequest`
declare const toApp: Handler;
// Validates that `req.user` is the owner of `req.app` record
// ~> NEEDS `req.user` & `req.app` to exist, provides no other changes
declare const isOwner: Handler;
// @ts-expect-error :: no `AppRequest` involved
compose(toUser, isOwner);
// @ts-expect-error :: no `UserRequest` involved
compose(toApp, isOwner);
// @ts-expect-error :: isOwner before `UserRequest` defined
compose(toApp, isOwner, toUser);
// @ts-expect-error :: isOwner before `AppRequest` defined
compose(toUser, isOwner, toApp);
// TYPE SAFE 🎉
compose(toUser, toApp, isOwner);
```
Of all the examples above, only the last line is (*_should be_) considered "type safe" because both `req.user` and `req.app` are defined before `isOwner` runs, which is a function that needs both of those properties to exist.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.