Adding to existing library typescript types with a new definition file

typescript custom type definition
typescript extend type definition
typescript declaration file
typescript override type definition
declare module typescript
typescript file structure
typescript local type definitions
typescript ignore file

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.

My current solution

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
};
Why I'm asking this question

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.

TypeScript: Adding Custom Type Definitions for Existing Libraries , In this case, we're going to make a new folder inside our src folder called customTypings to hold all our definition files, and then point TypeScript  The above won’t work because it’s not part of the TypeScript SDK, but rather it’s from an existing library (React) with existing definitions, and so it must be treated slightly differently. The step-by-step process to get to that definition is started by adding a property that does exist,

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.

Adding to existing library typescript types with a new definition file , 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  If you choose to write a complete and robust type file, this is a great article about how to do that, as well as DefinitelyTyped and TypeScript. Happy Typing! Karen is a front-end web developer at Detroit Labs who has a passion for creating beautiful, user-friendly, well-coded digital experiences, whether it be websites, applications, or any

I needed to do the same to add something to Knockout. I created a my-ko-additions.d.ts file and implemented it in the same way the Knockout declarations are done:

interface KnockoutStatic {
    additionalFunc1(input: string): string;
    additionalFunc2(input: string): string;
}

declare var ko: KnockoutStatic;

declare module "knockout" {
    export = ko;
}

Then I can implement and use these functions by just saying ko.additionaFunc1('abc').

Declaration Merging · TypeScript, This merged definition has the features of both of the original declarations. Type-creating declarations do just that: they create a type that is visible with the both declare a non-function member of the same name, but of different types. it is further extended by taking the existing namespace and adding the exported  There is a process that you can follow: Identify imports and exports of a given module. Identify types of the exported function (arguments and return). Create initial .d.ts file. Create test using a example from the module docs. Run test locally and fix issues. Send PR to DefinitelyTyped.

Migrating to Typescript: Write a declaration file for a third-party NPM , You have an existing node.js application with a lot of NPM modules. TypeScript uses declaration files to understand the types and function for example: So, the first step is to add a new directory to our project where we want to store our  Add Type Definitions To An External JavaScript File In TypeScript. Not too long ago I wrote an article that explained how to include external JavaScript libraries in an Angular TypeScript project. To summarize that post, my goal was to show how to use any of the millions of JavaScript libraries that exist online within a TypeScript application.

How to create your own TypeScript type definition files (.d.ts) and , In 99% percent of the libraries, the main file is the /src/index.js file but, We are going to add a new type definition file so we can say that we  You can have multiple interfaces and/or module with the same name, and TypeScript will merge them together, even if they are in different files. We can use this feature to extend the original Leaflet definition files. TypeScript supports at the moment 3 types of modules: internal, external and es6 modules.

Three Ways to Provide (TypeScript) Type Definitions to Open , Even though the library of type definitions is vast, the amount of convert the library to TypeScript, add type definition to the 3rd party library or add new configuration option, but the library's type definition file doesn't Everything starts by reading the Definitely Typed section on editing existing definitions. Referencing the type definition from within your TypeScript file. One last step! You need to make your TypeScript file aware of the definitions. In my case, I’m creating a file called map.ts, and I need to add the reference to jQUery within it. Without this reference, TypeScript will throw a warning, stating that it doesn’t know what the $ means.

Comments
  • Thanks @kimy82! So there's no way to augment the koa types globally in a koa.d.ts file? It seems odd that I can't do that, say even if I wanted to add types to DefinitelyTyped for koa-bearer-token would there be no way available to sub-library authors to add properties. So everytime anyone installs a sub-library like koa-bearer-token the properties the sub-library adds would always be incorrectly typed?
  • Thank you for the updated answer, that's worked! I initially named my file to koa.d.ts which still overwrote all the koa types but naming it something like koa-extensions.d.ts and importing Koa as per the answers example fixed the issue. For more info, I also just came across this issue which is highly relevant github.com/Microsoft/TypeScript/issues/10859