1

I have imported a module into the utility library I'm working on with the intent of augmenting and re-exporting it:

import * as ITE from "fp-ts/lib/TaskEither";

const foo = () => "foo";

export const TE = {
    ...ITE,
    foo
};

This works really well as I can import both the things that are in ITE and foo from my other modules. The problem is that the imported module (ITE) also declares an interface (TaskEither) that somehow doesn't get into the export so when I import TE elsewhere I can't see TE.TaskEither.

This is a bit unexpected because before doing this augmentation I was exporting the whole module like this:

export * as TE from "fp-ts/lib/TaskEither";

to enable VS Code to automatically import TE for me. What am I doing wrong with my current export? Is there a way to export not only the consts from ITE, but also the missing interface?

If I just re-add

export * as TE from "fp-ts/lib/TaskEither";

It fails as it conflicts with my local declaration of TE.

Adam Arold
  • 29,285
  • 22
  • 112
  • 207
  • doesn't simple `export * from "fp-ts/lib/TaskEither";` in your re-export module work? I.e. without TE, since you are naming it in your main module anyway. Export items separately that is (prefix the foo const with export) – Nikolay Aug 27 '23 at 13:33
  • The whole point is to have `TE` because it helps with VS Code auto-importing (eg: when I type `TE` it will automatically give me the option to import `TE.` So i need it to be an actual object. The only problem is that the `interface` is not exported when I re-export my imports. – Adam Arold Aug 27 '23 at 13:36
  • I see. Maybe you could provide a complete example (like, all 3 files, full source) to be able to easily reproduce. – Nikolay Aug 27 '23 at 13:39
  • This example can be used to fully reproduce the code. I literally have no more code. – Adam Arold Aug 27 '23 at 13:45
  • I mean, minimal example. Anyway. I don't think you can have an "interface" as a member of an object. In your expeort, you are building an object with fields. One of them is another const you grab using expansion (... syntax), but the interface is not picked up, as an object may contain only fields, not type definitions? – Nikolay Aug 27 '23 at 13:47
  • I already figured it out. You have to use a `namespace` and within it redeclare the `interface` as a `type` of the same name. – Adam Arold Aug 27 '23 at 13:48
  • 1
    Could you share the solution here? – Nikolay Aug 27 '23 at 13:49

1 Answers1

0

Typescript allows exporting a namespace with the same name (with declaration merging), so the solution is to add a type with the same name to the namespace in question:

import * as ITE from "fp-ts/lib/TaskEither";

const foo = () => "foo";

export const TE = {
    ...ITE,
    foo
};

export namespace TE {
    export type TaskEither<E, A> = ITE.TaskEither<E, A>;
}
Adam Arold
  • 29,285
  • 22
  • 112
  • 207