Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add TypeScript types to a JavaScript module without switching to TypeScript?

I guess the title is somewhat confusing, but I wasn't able to put it in a more concise way in a short title. However, this is what I want to do:

  • I have an npm module that is written in JavaScript, not TypeScript.
  • Some of the users of this module are using TypeScript, so it would be nice if I could provide type annotations for my JavaScript code.
  • But I do not want to switch to TypeScript, but I want to stick with pure JavaScript.

So, what I am looking for is some kind of an external type declaration manifest, or something like that.

Is this possible? If so, how?

Please bear with me if this is a naive question to TypeScript users, but I have absolutely no experience with TypeScript, and hence I do not know what to search the web for. Maybe if someone can push me into the right direction by giving me a name for what I am looking for, I am able to find a solution on my own.

like image 408
Golo Roden Avatar asked Dec 10 '18 17:12

Golo Roden


People also ask

Can you add types in JavaScript?

Javascript will remain a dynamically typed language, but it will accept type declarations natively. This specification is still stage 1, so a lot may change - but it's an exciting time for Javascript to take its first step into a more strongly typed world.

Can I import TypeScript into JavaScript?

Anything you can do with Angular in TypeScript, you can also do in JavaScript. Translating from one language to the other is mostly a matter of changing the way you organize your code and access Angular APIs.

Can I use TypeScript and JavaScript at the same time?

The TypeScript compiler supports a mix of JavaScript and TypeScript files if we use the compiler option --allowJs : TypeScript files are compiled. JavaScript files are simply copied over to the output directory (after a few simple type checks).


1 Answers

You will want to create Definition Files. These files are used to describe your JavaScript.

Let's say for simplicity you have a function called add, it will take two numbers or an array of numbers.

/src/index.js

exports.add = function add(a, b) {   if (Array.isArray(a)) return a.reduce((sum, val) => sum + val, 0)   else if (arguments.length === 2 && typeof a === 'number' && typeof b === 'number') return a + b   throw new Error('Invalid input')  } 

We can then create a definition file .d.ts, this will describe our JavaScript function. You should keep the file names and file structure the same as the JS within a root folder such as types.

/types/index.d.ts

/**  * Sums up two numbers.  *  * @param {number} a The first number to add.  * @param {number} b The second number to add.  * @returns {number} The resulting sum of the two numbers.  */ export declare function add(a: number, b: number): number /**  * Sums up a list of numbers.  *  * @param {number[]} numbers An array of numbers to add.  * @returns {number} The resulting sum of all the numbers.  */ export declare function add(numbers: number[]): number 

Note: When creating overloads, the most complex definition should be first and the least complex definition should be last, see Overload Ordering and all the Do's and Don'ts.

All that this file does is describe all of the functions/classes/interfaces/modules, etc. without any logic. Within the file you can create overloads as you can see from my example. This will allow you to define multiple ways that the function can be used. The file also supports JSDoc, so I would use it as well.

If you would like to split up a file into smaller files, you then need to include the file in the current file using a reference comment (it starts with three / and ends with />).

/// <reference path="./part-1.d.ts" /> /// <reference path="./part-2.d.ts" />  declare interface {   someProperty: string; } 

Next, we need to modify the package.json, this will tell the TypeScript parser where to find the definitions for this package.

/package.json

{   "types": "types/index.d.ts" } 

Note: The "typings" field is synonymous with "types", and could be used as well.

See Publishing for more information on package.json.

That is basically all there is to creating a .d.ts

like image 144
Get Off My Lawn Avatar answered Sep 23 '22 23:09

Get Off My Lawn