2
votes

I have written and npm published this: https://github.com/justin-calleja/pkg-dependents

Now I'm writing this package in Typescript: https://github.com/justin-calleja/update-dependents

I want to re-use a type defined in pkg-dependents (IndexInfoDict) in update-dependents and I want to check whether there's a better way of doing it than this:

In pkg-dependents's index.ts:

import { IndexInfoDict } from './interfaces';

export interface IndexInfoDict extends IndexInfoDict {};

i.e. I'm importing the IndexInfoDict interface to annotate a function in pkg-dependents's index.ts, but because I want to use this same type in update-dependents, I am forced to export another IndexInfoDict which extends itself…

It seems like a weird pattern but the compiler is now happy.


Note: additional steps taken to share the type:

  1. Use "declaration": true in tsconfig.json so a .d.ts file is generated for every .ts file which exports something.
  2. Use "typings": (path-to-generated-index.d.ts) in pkg-dependents's package.json so you can import index.js in your other Typescript project and it will know the index file's API via index.d.ts.
  3. To actually import the type and re-use it: import { IndexInfoDict } from 'pkg-dependents/lib/index.d.ts';

Can someone confirm that there isn't a better way?

What I would like, but don't know if it's possible, is to:

  1. Not have to export IndexInfoDict in a way that extends itself (I'm fine with just exporting the type… that makes sense).
  2. Somehow avoid use of 'pkg-dependents/lib/index.d.ts' in import. Can it just be import { pkgDependents, IndexInfoDict } from 'pkg-dependents' ... but since 'pkg-dependents' refers to a JS file (pkg-dependents's package.json's main is ./lib/index.js), I doubt whether this is possible.

Edit 1:

The more I think about it the more 2 above (avoid 'pkg-dependents/lib/index.d.ts') seems impossible. I was hoping tsc has some magic in it to figure out to get type definitions from 'index.d.ts' even though 'index.js' is being imported - that way I can just import { pkgDependents, IndexInfoDict } from 'pkg-dependents' from a Typescript project and just import { pkgDependents } from 'pkg-dependents' from a JS project (no tsc magic and JS doesn't have types anyway so IndexInfoDict is out).

Currently, I have to:

import pkgDependents from 'pkg-dependents';
import { IndexInfoDict } from 'pkg-dependents/lib';

So ok... maybe there's no magic. What about 1? Is there a less confusing way to export an imported type other than export one which extends itself?

(I'm using IndexInfoDic in more than one place in pkg-dependents. One of which happens to be index.ts, the main exported function. Because of this, I want it outside index.ts but exported from index.ts so it's generated in index.d.ts and users get the types used by the main function from index.d.ts).

1
I don't understand why you have to redefine IndexInfoDict? Why can you not just import { IndexInfoDict } from './interfaces'; wherever you need it? - Matt Lishman
@MattLishman you're right. My reasoning was "I want everything users of pkg-dependents will need to be in one place". That one place cannot be index.js (interface types won't go there). So /lib/index.t.ds is a second best place. Users will still need 2 import stmts but at least no need to remember the interfaces dir's path. I import IndexInfoDict and export it again in index.ts so it will be generated in index.d.ts and users have one place to get the main code and a related place to get main code types (they just need to know its in /lib/index.t.ds). - justin
@MattLishman as I've continued, I've realised that in order to keep the main types in index.t.ds, I'll need to import/export other types out of which IndexInfoDict is made (leaving only one which is only used internally). Maybe this is not worth it, but I like having one place for all types in project pkg-dependents (src/interfaces) and then be able to choose what types get exported in index.t.ds. But maybe this does not make sense? Maybe all types should be "public"… - justin

1 Answers

3
votes

In your index.ts, You can do:

export { IndexInfoDict } from "./interfaces;

This will export the interface from the main file.