typescriptnode-modulestypescript-declarations

Exposing external module TypeScript declarations to consuming modules


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?


Solution

  • 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.