You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Non-exported classes in type declaration files leaking value names #32182
Search Terms: ambient module declaration export declare class type name
Code
In a file called classes.d.ts:
declareclassA{}exportdeclareclassBextendsA{}
In a file called test.js:
leta=require('classes').A;
In a file called test.ts:
import{A}from'./types/classes';
[NEW] Assumptions:
The following is a list of assumptions I had when originally opening this issue:
Type Declaration Files work like modules: once you use import or export [on a top-level declaration], only explicitly exported declarations are visible externally.
Type names declared in a Declaration File are always accessible via import types (at least those that are used by exported types.
E.g. export class B extends A exports the type names A and B, even if A was not directly exported.
Value names declared in a module-style Declaration File (see #1 above) are only accessible if explicitly exported.
These assumptions are the result of reading the documentation and working with declaration files. Note that the documentation does not mention:
In a declaration file everything is implicitly exported. You can prevent that by adding export{};.
With that change you can also no longer use A as type. To fix that you need to export it as interface.
Rename the A class to AClass and export a type: export type A = AClass;.
Rename the A class to AClass and export an interface: export interface A extends AClass {}.
Here are the issues with those options:
Converting to a class is undesirable as it requires adding all properties to classes that implement the type. For a base class with 24 documented properties, this is untenable.
While using a type alias results in IntelliSense autocomplete [in VSCode] correctly showing the type as a class, the type shown on hover reads as the resolved AClass. Which is not the desirable information to convey.
IntelliSense autocomplete [in VSCode] shows the type as an interface rather than a class.
In my opinion, the third option is the best of the bunch.
Is there really no way to [meaning-full-y] export the type of a class rather than both its typeandvalue?
Reacted by Zuri Klaschka, msheakoski, nenw* and Ilya Golovin
changed the title [-]Non-exported classes in type declaration files leaking names[/-][+]Non-exported classes in type declaration files leaking value names[/+]on Jul 1, 2019
Activity
ericdrobinson commentedon Jun 29, 2019
Without support for this it is extremely difficult to model a module that has a private base class with many public subclasses.
The following is a snippet of JavaScript:
The
importtype currently works as expected. 👍The
instanceofline beneath it does not report the expected error. 👎ajafff commentedon Jun 30, 2019
In a declaration file everything is implicitly exported. You can prevent that by adding
export{};.With that change you can also no longer use
Aas type. To fix that you need to export it as interface.ericdrobinson commentedon Jun 30, 2019
Is that documented anywhere? That should really be documented.
This should also be documented. Does this syntax have a name?
Klaus Meinhardt (@ajafff) What do you mean that you can "export it as interface"?
I see three options:
Aclass toAClassand export a type:export type A = AClass;.Aclass toAClassand export an interface:export interface A extends AClass {}.Here are the issues with those options:
class, the type shown on hover reads as the resolvedAClass. Which is not the desirable information to convey.interfacerather than aclass.In my opinion, the third option is the best of the bunch.
Is there really no way to [meaning-full-y] export the
typeof a class rather than both itstypeandvalue?[-]Non-exported classes in type declaration files leaking names[/-][+]Non-exported classes in type declaration files leaking value names[/+]