0
votes

I'm writing typings for a package to contribute to DefinitelyTyped, so the file I'm creating will be resolved in module context. This is simple enough, along the lines of

import { A } from "package-a";
export function B(): void;

However, I'd like to declare a few types and interfaces that are not useful to consumers of the package, but make the declarations easier to read and write:

type ArgType = string | ArrayBuffer | Uint8Array | Readable | ReadableStream;
export function foo(x: ArgType): void;
export function bar(x: ArgType): string;
export function baz(x: ArgType): number;

The problem is, as soon as I declare ArgType at the top level, it's actually exported from the module along with foo, bar, and baz. This means ArgType shows up in the language service for auto-complete, etc, which looks messy. It also happens with interfaces and namespaces.

dtslint has an error for this, strict-export-declare-modifiers, which is how I first discovered this behavior. As far as I can tell, this isn't a problem when writing an actual TS module (vice a declaration / typings file). Is it not possible to declare something in this file that the consumer won't see?

1

1 Answers

1
votes

The only way I know to do this is to declare a namespace with your intended exports, use an export assignment to make that namespace the top-level export, and then put your auxiliary definitions outside the namespace:

type ArgType = string | ArrayBuffer | Uint8Array | Readable | ReadableStream;
declare namespace Exports {
    function foo(x: ArgType): void;
    function bar(x: ArgType): string;
    function baz(x: ArgType): number;        
}
export = Exports;

I'm not sure this is considered recommended practice (does anyone know?), and you lose the ability to declare a default export. IMO, if you thought a type or interface was useful to write the declarations, it is bound to be useful to someone, somewhere, writing a wrapper for the library, so I would just export it.

Update 2018-09-30

By accident, Luke Pighetti discovered a real solution: including at least one export {...} statement, even an empty one, suppresses the default behavior of exporting all symbols even if they aren't marked export. According to andy-ms, this is supported TypeScript behavior.

type ArgType = string | ArrayBuffer | Uint8Array | Readable | ReadableStream;
export function foo(x: ArgType): void;
export function bar(x: ArgType): string;
export function baz(x: ArgType): number;
export {};