This blog post, like most, is for my own edification. Organizing TypeScript modules is hard for me. These notes are from the official TypeScript module advice.

namespaces

  • these were previously "internal modules"
  • avoid, unless there is a strong reason

modules

  • these were previously "external modules"
  • a module hides its members
  • expose members with export
  • consume exported members with import
  • a file containing a top-level import/export is a module

export

  • we can export any module member
  • e.g. variable, function, class, interface...
  • exports have several useful forms
  • export { Foo };
  • export { Foo as Bar };
  • export class Foo { }
  • export { Foo as Bar } from "./Foo";
  • export * from "./Foo";
  • export default class Foo { } // inline default
  • if inline default fails, use this form
  • export default MyEnum
  • export default IMyInterface

import

  • we can import any member that modules export
  • imports have several useful forms
  • import { Foo } from "./Foo";
  • import { Foo as Bar } from "./Foo";
  • import * as Foobar from "./Foo";
  • import "./Foo"; // side-effects only
  • import foo from "./Foo"; // with default
  • import bar from "./Foo"; // with rename

export advice

  • avoid nesting
  • export classes; avoid using namespaces
  • export functions; avoid using static methods
  • if a file has a single export
  • then use export default
  • else use multiple export statements
  • re-export when extending
  • e.g. export { SubClass as ParentClass }

import advice

  • list each named item import { x, y, z } ...
  • if lots, use a namespace import * as Foo ...

For more details, read the official modules advice from TypeScript.