Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I write and use custom declaration files that don't exist on @types or DefinitelyTyped?

I'm using an npm package called foo that doesn't exist on DefinitelyTyped. In other words, @types/foo doesn't exist (or is potentially out of date!)

I'd like to still be able to consume it under stricter settings like noImplicitAny, so I need to write the custom definition files myself. Eventually I would like to send a pull request to DefinitelyTyped so that this file can be useful to others outside of my project.

There are easy solutions like creating a global file named ./src/types.d.ts where I can write the following

declare module "foo" {
    export function hello(): void;
    export function world(): void;
}

But if I use that syntax, I'll potentially need to rewrite my module when I submit it to DefinitelyTyped.

How can I structure my project so that I can easily author and then send local .d.ts files to DefinitelyTyped?

like image 217
Daniel Rosenwasser Avatar asked Jun 28 '17 07:06

Daniel Rosenwasser


People also ask

Could not find a declaration file for module stream?

The error "Could not find declaration file for module" occurs when TypeScript cannot find the type declaration for a module. To solve the error, install the types for the module by running the command from the error message, e.g. npm install -D @types/module-name .

What is the use of D TS file?

d. ts is the type definition files that allow to use existing JavaScript code in TypeScript. declare function sum(a: number, b: number): number; From now on, we can use the function in TypeScript without any compile errors.


1 Answers

I'll do this step-by-step with explanations so this may seem lengthy, but following the instructions given should take just a few minutes. In fact, here's the short version you can just run in either bash or PowerShell!

mkdir -p ./local-types/foo
cd ./local-types/foo
npm init --scope types --yes
echo "export function hello(): void; export function world(): void" > ./index.d.ts
cd ../..
npm install ./local-types/foo

Background

Let's imagine the following project structure:

proj/
├─ tsconfig.json
└─ src/
   └─ ...

Create a local-types folder at the root of your project.

Doesn't matter what it's called, but we'll call it local-types. You can change it to whatever you want once you have a good grasp on what we've done here.

proj/
├─ tsconfig.json
├─ local-types/
└─ src/
   └─ ...

In most cases outside of this example, I might just name this types.

Create a new package in your local types directory

Since you're trying to import a module named foo, we'll create a folder named foo with an index.d.ts.

// local-types/foo/index.d.ts

export function hello(): void;

export function world(): void;

We'll also want to make this an npm package by creating a package.json:

cd local-types/foo
npm init --scope types --yes

At this point, your project should look like this:

proj/
├─ tsconfig.json
├─ local-types/
|  └─ foo/
|     └─ index.d.ts
|     └─ package.json
└─ src/
   └─ ...

You should now be able to just import foo from any file within src.

import { hello, world } from "foo";

hello();
world();

Keep in mind, you may not have a single-entry-point package with an index.d.ts. In that case, you'll want to mimick the package structure as it's been published on npm.

Add the package as a dependency (or potentially devDependency)

If you're writing a library, you'll likely want this in your dependencies, but apps might want to use devDependencies. Simply add file:./local-types/foo as the version for @types/foo:

"dependencies": {
    "@types/foo": "file:local-types/foo"
}

Publish to DefinitelyTyped

Are your .d.ts files complete and useful? Consider writing some tests and sending a pull request to DefinitelyTyped so that others can benefit from the work you've done!

If you're able to import those packages with no problems at runtime, you'll already have the appropriate package structure.

Things to keep in mind

  • Don't use the declare module "..." syntax within any of these local type packages.
    • ...unless you're trying to write a module augmentation. But you probably aren't.
  • Make sure your files have at least one import or export unless they are truly script/global files.
  • Follow advice given from the TypeScript website on authoring declaration files.
like image 115
Daniel Rosenwasser Avatar answered Sep 29 '22 11:09

Daniel Rosenwasser