2

I have a published TypeScript module (let's call it shared-stuff) that is designed to be imported by other TypeScript modules. This shared-stuff module has third-party dependencies that have no @types-scoped declarations, so inside of that module there are several declaration files:

/lib/declarations/
  something.d.ts
  another-thing.d.ts

These declaration files work fine within the context of shared-stuff. However, once the consuming app starts importing from shared-stuff, TypeScript gives me errors like:

Could not find a declaration file for module 'another-thing'.

I can work around this challenge by having the consumer explicitly import the .d.ts files from the dependency, but this is not ideal since every consumer would have to do that same thing.

Is there a way to have a consuming module "inherit" the declarations from a dependency?

Jacob
  • 77,566
  • 24
  • 149
  • 228

2 Answers2

2

Since your consumer (consumer of shared-stuff) relies on the typings of another-thing, you need to export them too.

One way to do that is using /// <reference> in your index.ts (and remember to include your /lib/declarations in your distribution.

Another way is don't rely on the external typings. i.e., instead of doing:

import { SomeType } from 'another-thing'
export function foo(): SomeType { ... }

Define that type yourself (inside shared-stuff, instead of in another-thing.d.ts):

export type SomeType = { ... }
export function foo(): SomeType { ... }

In theory, the types in another-thing should follow semantic version as the library itself, but in reality it is much more prone to breaking changes.

One reason is that the library was not written in TypeScript to begin with, so the library author may accidentally break the types without aware of it.

Therefore, while declaring the types yourself sound fragile comparing to reusing type, it really isn't. (and in your case you are defining them yourself anyway).

Just make sure you have a good suite of tests to catch any type breaking changes.

unional
  • 14,651
  • 5
  • 32
  • 56
-1

Is there a way to have a consuming module "inherit" the declarations from a dependency?

The conventional way is to have it as a peerDepenency and mention in your docs that its required for use e.g. for react:

npm i shared-lib react @types/react

AKA you bring your own version of react / @types/react

basarat
  • 261,912
  • 58
  • 460
  • 511
  • My question is about declarations that are not in installable `@types` modules but those that are declared in `.d.ts` files local to `shared-stuff`. – Jacob Feb 01 '19 at 01:05
  • Make them available as installable modules – basarat Feb 01 '19 at 02:59