Skip to content

Commit b6565d0

Browse files
committed
Tweaks to work better in practice with freeway
* Generate `composeMiddleware` overloads up to 30 arguments. * Use file extensions in `import`s. * Use `Simplify` in the return type of `composeMiddleware` for better ergonomics. * Add `extends {}` to the type parameters of a `Middleware` function--I don't actually remember why, but the types didn't infer correctly otherwise. * Use `const`s instead of `function`s for middleware functions. The `@type` tag doesn't apply correctly to a `function` declaration--which makes sense, since there's no equivalent syntax that would do it in TypeScript: microsoft/TypeScript#27387
1 parent 1b5fccc commit b6565d0

File tree

4 files changed

+2190
-456
lines changed

4 files changed

+2190
-456
lines changed

scripts/generateComposeMiddleware.js

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import ts from 'typescript'
33
import * as prettier from 'prettier'
44

55
// The maximum number of arguments to generate overloads for.
6-
const MAX_ARGUMENTS = 20
6+
const MAX_ARGUMENTS = 30
77

88
/**
99
* Simply passes the value {@link x} to the function {@param fn} and returns the
@@ -40,7 +40,7 @@ const declarations = [
4040
EnvOf,
4141
Middleware,
4242
RequiredContextOf,
43-
} from './bindings'
43+
} from './bindings.js'
4444
4545
/**
4646
* Returns the result of satisfying the {@link Requirements} with the
@@ -50,6 +50,12 @@ const declarations = [
5050
With extends Pick<Requirements, keyof Requirements & keyof With>
5151
? Omit<Requirements, keyof With>
5252
: never
53+
54+
/**
55+
* Forces TypeScript to resolve a complex type into a simple single object
56+
* type. This makes the type of a composed middleware much easier to read.
57+
*/
58+
type Simplify<T> = {[KeyType in keyof T]: T[KeyType]} & {};
5359
`,
5460

5561
/* typescript */ `
@@ -87,6 +93,7 @@ function createComposeMiddlewareOverloadDeclaration (argCount) {
8793
undefined,
8894
'composeMiddleware',
8995
[
96+
// Type parameters
9097
...ns.flatMap((n) => {
9198
return [
9299
ts.factory.createTypeParameterDeclaration(
@@ -125,6 +132,8 @@ function createComposeMiddlewareOverloadDeclaration (argCount) {
125132
]
126133
})
127134
],
135+
136+
// Function parameters
128137
ns.map((n) =>
129138
ts.factory.createParameterDeclaration(
130139
undefined,
@@ -135,31 +144,39 @@ function createComposeMiddlewareOverloadDeclaration (argCount) {
135144
undefined
136145
)
137146
),
147+
148+
// Return type
138149
ts.factory.createTypeReferenceNode('Middleware', [
139-
ts.factory.createIntersectionTypeNode(
140-
ns.map((n) =>
141-
withBinding(
142-
ts.factory.createTypeReferenceNode('RequiredContextOf', [
143-
ts.factory.createTypeReferenceNode(`M${n}`)
144-
]),
145-
(requiredContext) =>
146-
n === 1
147-
? requiredContext
148-
: ts.factory.createTypeReferenceNode('Satisfy', [
149-
requiredContext,
150-
ts.factory.createTypeReferenceNode(`M${n - 1}C`)
151-
])
150+
ts.factory.createTypeReferenceNode('Simplify', [
151+
ts.factory.createIntersectionTypeNode(
152+
ns.map((n) =>
153+
withBinding(
154+
ts.factory.createTypeReferenceNode('RequiredContextOf', [
155+
ts.factory.createTypeReferenceNode(`M${n}`)
156+
]),
157+
(requiredContext) =>
158+
n === 1
159+
? requiredContext
160+
: ts.factory.createTypeReferenceNode('Satisfy', [
161+
requiredContext,
162+
ts.factory.createTypeReferenceNode(`M${n - 1}C`)
163+
])
164+
)
152165
)
153166
)
154-
),
155-
ts.factory.createTypeReferenceNode(`M${ns[ns.length - 1]}C`),
156-
ts.factory.createIntersectionTypeNode(
157-
ns.map((n) =>
158-
ts.factory.createTypeReferenceNode('EnvOf', [
159-
ts.factory.createTypeReferenceNode(`M${n}`)
160-
])
167+
]),
168+
ts.factory.createTypeReferenceNode('Simplify', [
169+
ts.factory.createTypeReferenceNode(`M${ns[ns.length - 1]}C`)
170+
]),
171+
ts.factory.createTypeReferenceNode('Simplify', [
172+
ts.factory.createIntersectionTypeNode(
173+
ns.map((n) =>
174+
ts.factory.createTypeReferenceNode('EnvOf', [
175+
ts.factory.createTypeReferenceNode(`M${n}`)
176+
])
177+
)
161178
)
162-
)
179+
])
163180
]),
164181
undefined
165182
)

src/bindings.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export type Middleware<
8080
* handler.
8181
* @template HandlerEnv The environment keys used by the wrapped handler.
8282
*/
83-
<HandlerRequiredContext, HandlerEnv>(
83+
<HandlerRequiredContext extends {}, HandlerEnv extends {}>(
8484
h: Handler<AddedContext & HandlerRequiredContext, Env & HandlerEnv>
8585
) => Handler<RequiredContext & HandlerRequiredContext, Env & HandlerEnv>
8686

0 commit comments

Comments
 (0)