serge
serge

Reputation: 15239

Why does exporting an interface, enum or type not create a module in TypeScript?

I have the following TS file (enums.ts) I try to import in another file

export interface ZZZ { 
  z: number
}

export const enum EnumTest {
  T2,
  T3,
  XY
}

export type EnumTest_Strings = keyof typeof EnumTest;

export function toto(){ }; // commenting this 'removes' the module

If I remove the last line, I can't import anything in the other file. It says it does not find a module "./enums".

Is there a way to create a module without having to declare functions?

Upvotes: 4

Views: 470

Answers (1)

Olian04
Olian04

Reputation: 6872

For const enum

You will want to enable preserveConstEnums in your tsconfig.json file.

preserveConstEnums: Do not erase const enum declarations in generated code. const enums provide a way to reduce the overall memory footprint of your application at runtime by emitting the enum value instead of a reference.

With preserveConstEnums enabled then this typescript code:

export interface ZZZ { 
  z: number
}

export const enum EnumTest {
  T2,
  T3,
  XY
}

export type EnumTest_Strings = keyof typeof EnumTest;

Will result in this javascript code:

export var EnumTest;
(function (EnumTest) {
    EnumTest[EnumTest["T2"] = 0] = "T2";
    EnumTest[EnumTest["T3"] = 1] = "T3";
    EnumTest[EnumTest["XY"] = 2] = "XY";
})(EnumTest || (EnumTest = {}));

playground

For regular enum

Alternatively you can use a regular enum instead of a const enum.

With a regular enum then this typescript code:

export interface ZZZ { 
  z: number
}

export enum EnumTest {
  T2,
  T3,
  XY
}

export type EnumTest_Strings = keyof typeof EnumTest;

Will result in this javascript code:

export var EnumTest;
(function (EnumTest) {
    EnumTest[EnumTest["T2"] = 0] = "T2";
    EnumTest[EnumTest["T3"] = 1] = "T3";
    EnumTest[EnumTest["XY"] = 2] = "XY";
})(EnumTest || (EnumTest = {}));

playground

Difference between enum & const enum

Regular enum:s are:

  • More coprehensive than const enum:s
  • Compiled down to javascript object

const enum:s are:

  • More restrictive then regular enum:s
  • Compiled "away" during transpilation.

This means that const enum:s wont be accessible during runtime (or as part of a library), however const enum:s leave less of a footprint in the resulting javascript. For example: console.log(EnumTest.XY) will either transpile to console.log(EnumTest.XY) if EnumTest is a regular enum, or it will transpile to console.log(2 /* XY */) if EnumTest is a const enum.

playground

Regarding interface and type

These are "just" types, they won't be accessible or relevant in vanilla javascript in any shape or form, so typescript won't include them in any way in the build output by default. You can still include them in your output in the form of a type declaration if you enable declaration in your tsconfig.json. This wont change your codes behavior during runtime or during interop with javascript. But it will allow other typescript files to import your transpiled javascript as if it was regular typescript.

With declaration enabled then this typescript code:

export interface ZZZ { 
  z: number
}

export enum EnumTest {
  T2,
  T3,
  XY
}

export type EnumTest_Strings = keyof typeof EnumTest;

Will result in this declaration file (.d.ts) alongside your javascript:

export interface ZZZ {
    z: number;
}
export declare enum EnumTest {
    T2 = 0,
    T3 = 1,
    XY = 2
}
export declare type EnumTest_Strings = keyof typeof EnumTest;

playground

Upvotes: 2

Related Questions