I’m using this library https://github.com/chentsulin/koa-bearer-token which adds an extra property to the koa libraries request object like ctx.request.token
. So if I use the koa types directly I get an error which tells me the token
property doesn’t exist on ctx.request.token
.
I created a type definition file called koa-bearer-token.d.ts
which contains types for the library and exports for the extended koa context/request type:
declare module 'koa-bearer-token' {
import {Context, Request, Middleware} from 'koa';
interface Options {
queryKey?: string;
bodyKey?: string;
headerKey?: string;
reqKey?: string;
}
interface RequestWithToken extends Request {
token?: string
}
interface ContextWithToken extends Context {
request: RequestWithToken
}
export default function bearerToken(options?: Options): Middleware;
export {RequestWithToken, ContextWithToken};
}
Then I use this in other files like:
import {ContextWithToken} from 'koa-bearer-token';
const someFunction = (ctx: ContextWithToken) => {
const token = ctx.request.token; // <-- No longer errors
};
This works now but I’m concerned it isn’t the best way because it wouldn’t work if I need to add more properties in the future, ideally I want to just create a koa.d.ts
file that adds to the libraries types then I can carry on using import {Context} from 'koa';
instead of import {ContextWithToken} from 'koa-bearer-token';
but when I create koa.d.ts
it overwrites all the library types instead of adding on top of them.
Here is my tsconfig.json in case it helps
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"noImplicitAny": true,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
"baseUrl": ".",
"paths": {
"*": [
"node_modules/*",
"src/@types/*"
]
}
},
"include": [
"src/**/*"
]
}
You can try with module augmentation. You don't have to declare a new module. Typescript is going to merge both modules and you should have the legacy koa typings plus your new ones.
import * as koa from "koa"
declare module 'koa'{
interface Request {
token: string;
}
}
declare const c: koa.Request;
c.token = 'tre';
The tricky thing is that it has to be placed just after the koa import. So, I would suggest to set this new change in a separated file so it is easy to apply your change everywhere.
import * as koa from "koa";
import '<path to>koachanges';
Hope that helps
Regarding you have said, I would say it is possible.
Change your tsconfig in order to add a global d.ts file.
...
"typeRoots": ["./node_modules/@types", "./typings"]
...
Add an index.d.ts file in this new typings folder in the root directory of your project and place in it.
import * as Koa from 'koa';
declare module 'koa'{
interface Request {
token: string;
}
}
It is important to add the first import as then is importing the koa typings to your global file and then you can override them.
An alternate more extensible solution to adding the types to koa-bearer-token.d.ts
would be to add a file like koa-extensions.d.ts
and add any extra properties there like so:
import {Context, Request} from 'koa';
declare namespace KoaExtensions {
interface KoaRequest extends Request {
token?: string
}
interface KoaContext extends Context {
request: KoaRequest
}
}
export = KoaExtensions;
Then the extended types can be imported:
import {KoaContext} from './@types/koa-extensions';
const someFunction = (ctx: KoaContext) => {
const token = ctx.request.token; // <-- No longer errors
};
This is an improvement on my initial solution but it still seems like I should be able to globally augment the Koa module types in a local koa.d.ts
file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With