Add your own Type Definition to any Javascript 3rd party module

Intended audience

3 min readMay 2, 2020

--

Any programmer using typescript, whether if you’re a frontend or a backend developer, and need to write your own type definition to a 3rd party javascript module.

Adopting Typescript

Intro

There is a lot of modules in the open-source community, for us to use in our projects, whether if it‘s a NPM module or some library stored on a CDN.

Some of those modules were written in typescript, so typescript support will come out of the box, without any necessary action by the developer using it.
Thet’s not in our case, most of the open-source modules were originally written in Javascript, and later on, a separate type definition module was published (by the community of the original developers' team).

A nice explanation of what are Type Definition Declaration files I’ve heard recently was :
xx.d.ts - declaration files for typescript are what xxx.h - headers files are for C++,
if that doesn't tell you anything read this section in the typescript handbook .

So, a common scenario, and the one we dealing with right now, is where you integrate the 3'rd party module, which was originally written in javascript, into your typescript project, and doesn't have any typescript support out there.

Side note — not in any case Typescript support is necessary, on a simple javascript module, where the usage is straight forward and short, the effort of writing and configure a custom type-definition might not be worth it.

In my specific case, I needed to use PayPal server-side SDK in my NodeJs project, I’ve installed the PayPal official package @paypal/checkout-server-sdk that does a great job wrapping the V2 payment API.
But unfortunately, I could not find any Typescript support, and the simple beginner's guide sample didn't cut it.

First, get familiar with the tsconfig.json file and its capabilities,

Overview : The presence of a tsconfig.json file in a directory indicates that the directory is the root of a TypeScript project. The tsconfig.json file specifies the root files and the compiler options required to compile the project.

Further reading here.

A major repository maintaining most of the type definitions modules out there is DefinitelyTyped, take a look, it could be useful.

Problem definition

We want to use and integrate into our Typescript project, a 3rd party module, written in javascript, that doesn’t have any type-definition support.

Solution definition

Write a minimal type definition declaration file to the 3rd party module, one that covers only what we need, (consider that this is only a subtask of our main project).
Configure our project to handle the customs declaration file as if it was NPM installed.

Define the working ground first :

  • The 3rd party module name is @org-name/package-name
  • Typescript version typescript@3.7.5
  • IDE VSCode version: 1.44.2
  • The tsconfig.json file in our project looks something like
basic tsconfig.json file
  • Project folder structure :
project/
└───package.json
└───tsconfig.json

└───src/
│ └───project-files ...
│ └───...

└───node-modules/
│ └─── ...

Solution walkthrough

Step 1 :

Create a folder where you will store the declaration file,
for example, src/local-types.
In that folder, create another folder named as the 3rd party module name,
in our case the module is a scoped npm package, you can see that by the @xxx/ prefix, in a case like this, we omit the @ and replace the / with __ (double underscore),
e.g: for@org-name/package-name the folder name will be org-name__package-name.

Step 2 :

In the folder src/local-types/org-name__package-name, create a declaration file, where you will write the module’s type definition, name index.d.ts (.d.ts is the default typescript declaration file extension).

In the index.d.ts file write a simple declaration expression, like :

declare module MainModuleName {
class ClassName {}
}
export = MainModuleName;

here’s a helpful example of the type declaration syntax.

Step 3 :

On the tsconfig.json file add the flowing :

1. To the typeRoots property add your local-types folder path.

"compilerOptions" : {
...
"typeRoots": [
"node_modules/@types",
"src/local-types"
]
}

2. Add a paths property under the compilerOptions property, with the alias name you will use to import the module.

3. Exclude any file under local-types folder from being compiled.

"exclude": [
"node_modules",
"src/local-types/**"
]

Check the module you need to import, your IDE should hint the type definition you configured.

You're Done 👏🏽 .

--

--

Ofir G
Ofir G

Responses (2)