mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2025-10-16 12:05:41 +00:00
* [@types/koa]: Parameterize `Context` and `Application`.
Currently, `ctx.state` is `any`, and `ctx` itself allows any fields to
be inside `Context`. That's essentially 2 places where developers can
add their custom properties, and would be great to opt-in into more
typesafe approach than it's currently is.
What if we parameterize `Context` and `Application` with 2 types - one
will define `ctx.state`, and another - fields in `Context`? Then, if you
chain `use`, TypeScript will infer the types properly for your
middlewares. Like:
```typescript
interface NewContext {
orgh: string;
}
interface FooState {
foo: string;
}
interface BarState {
bar: string;
}
async function fooMiddleware(
ctx: Koa.Context<FooState>,
next: () => Promise<void>
): Promise<void> {
ctx.state.foo = "foo";
await next();
}
async function barMiddleware(
ctx: Koa.Context<BarState>,
next: () => Promise<void>
): Promise<void> {
ctx.state.bar = "bar";
await next();
}
const app = new Koa<{}, {}>()
.use(fooMiddleware)
.use(barMiddleware)
.use<{}, NewContext>(async (ctx, next) => {
// Here ctx is inferred as Koa.Context<FooState & BarState, NewContext>
ctx.orgh = "bazinga";
await next();
})
.use(async (ctx, next) => {
// Here ctx is inferred as Koa.Context<FooState & BarState, NewContext>
await next();
});
// `app` here is `Koa<FooState & BarState, NewContext>`
app.listen(3000);
```
So, if you define `const app = new Koa<{}, {}>()`, then you'll opt-in
into "typesafe" Koa Context. But if you do just `const app = new Koa()`,
you still will have `ctx.state: any`, like before. So, it should be
backwards-compatible.
But even in this case you can specify what the `ctx` is inside
the middlewares, like:
```typescript
const app2 = new Koa();
app2.use(fooMiddleware);
app2.use(async (ctx, next) => {
// `ctx.state` here is inferred as `any`
ctx.state.prop = "Some Prop";
await next();
});
app2.use(async (ctx: Koa.Context<{}, NewContext>, next) => {
ctx.orgh = "oh yeah";
await next();
});
app2.use(async (ctx: Koa.Context<FooState>, next) => {
ctx.state.foo = "Yay";
await next();
});
```
What do you think?
* Rename new `Context` to `ParameterizedContext`
So that all the old hacks with declaration merging of Koa's `Context`
wouldn't break.
* Fix the build
* Use Context instead of ParameterizedContext when possible
|
||
|---|---|---|
| .. | ||
| index.d.ts | ||
| koa-tests.ts | ||
| tsconfig.json | ||
| tslint.json | ||