pseudosudo
pseudosudo

Reputation: 6590

Namespace with the same name as type alias in the same file

I've come across a pattern that can be summarized as:

export namespace Foo {
    export enum Bar {}
}
export type Foo = Omit<typeof Foo, 'Bar'>

(Original code here.) With my rudimentary understanding of typescript, what I think this is doing is:

  1. declaring a namespace Foo
  2. Taking typeof Foo to create a type from that namespace.
  3. Omitting Bar from the type created in 2, and aliasing this type to identifier Foo.

So far so good, I think, but please correct me if I'm wrong. At this point things get into magic territory for me. This is because when Foo is imported from another file, somehow magically the namespace Foo is imported, rather than the type alias Foo. My questions are:

  1. Does the second file import the right Foo due to type inference magic or is there something else going on here that I should know?
  2. Back to the original file declaring the two Foos, is it at all weird that we have two things with the same name without a name collision? Is the collision avoided by the fact that namespaces are objects and type aliases are types?
  3. Is this a common pattern in TypeScript? Is it a good pattern? Should I be writing code like this?

Upvotes: 0

Views: 1300

Answers (1)

Szabolcs D&#233;zsi
Szabolcs D&#233;zsi

Reputation: 8843

Your thinking is correct with regards to what the code is doing.

  1. Yes, the compiler infers whether it refers to the type alias or the namespace based on the usage.

For example: https://github.com/rokoroku/react-redux-typescript-boilerplate/blob/master/src/app/components/TodoList/index.tsx#L10

Here, TodoActions is used as a type, so the compiler knows that it refers to the exported type alias.

Another example: https://github.com/rokoroku/react-redux-typescript-boilerplate/blob/master/src/app/reducers/todos.ts#L16

Here, TodoActions.Type.ADD_TODO is used to create a property, so the compiler, again, knows that it refers to the namespace.

You can actually see this if you hover over the identifier in VS Code:

Type

Namespace

  1. and 3.) It can be a little confusing at first, but this is intended behavior. I personally would avoid it though, as it can cause unnecessary confusion.

The following article explains the exact question you have: https://www.typescriptlang.org/docs/handbook/declaration-files/deep-dive.html

Upvotes: 1

Related Questions