Adding properties to Koa2's context in Typescript

Just figured out an approach that doesn't require any type-hacking:

interface ICustomAppContext {
  mySlowToInitializeClient: string;
}

interface ICustomAppState {
  poop: string;
}

const app = new Koa<ICustomAppState, ICustomAppContext>();

See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b081a5b7d0db7181901d7834f8a85206af263094/types/koa/index.d.ts#L434 for details.


Take a look at Module Augmentation to understand more how this works.

You can indeed do something like:

import { Context } from "koa";

declare module "koa" {
    /**
     * See https://www.typescriptlang.org/docs/handbook/declaration-merging.html for
     * more on declaration merging
     */
    interface Context {
        myProperty: string;
        myOtherProperty: number;
    }
}

OK, well I guess I still have a lot to learn. The solution to the typing problem seems to be...

import { BaseContext } from 'koa';

declare module 'koa' {
  interface BaseContext {
    dataLoader(): any;
  }
}

And, because BaseContext is an interface and not a class, you have to define the dataLoader implementation after you have instantiated Koa's Application class.

const app = new Application();

app.context.dataLoader = function() {
  console.log('OK, this works.');
}

app.context is the prototype used to create each request's context object.

I'd appreciate any comments regarding the correctness of this answer. Thanks.

Ah... learning in public.