Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
July 25, 2021 10:18 am GMT

TypeScript: Namespace declaration merging for organizing types

Introduction

Declaration merging is a concept in TypeScript which means the TS compiler will merge two or more separate declarations with the same name into one single declaration.

Ambient namespace declaration

A TypeScript namespace allows you to access its exported values or types using dot-notation. While it's not recommended to use namespace in today's code (hello, not standard EcmaScript), it's still recommended and useful for describing and organizing types.

An ambient namespace declaration is a fully erasable (at compile time) namespace declaration. In other words, it doesn't emit any code.

How is this useful?

An ambient namespace declaration can be merged with type aliases, interfaces, classes, and even functions. This allows you to access namespace's exported types using dot notation which is useful for organizing code.

How to do it?

Append the declare keyword in front of the namespace keyword to make it an ambient declaration. Then use the same name of the entity (interface / type / class / ...) that you want to merge with as the namespace name. Look at the following examples:

Organizing sub types and interfaces

Instead of exporting User and UserDetails interfaces, we can just define a single User interface and use ambient namespace declaration to export sub types:

// example.tsinterface User {  FirstName: string  LastName: string  Details: User.Details}declare namespace User {  interface Details {    Address: string  }}const details: User.Details = {  Address: "Somewhere over the rainbow"}const user: User = {  FirstName: "Bob",  LastName: "Alice",  Details: details,}

Note that because we're using declare keyword, there is no need to export the Details interface (auto-exported).

Exposing interface property types

Sometimes it's useful to expose interface's property types. For instance, branded types:

// example.tsinterface User {  FirstName: User.FirstName  LastName: User.LastName}declare namespace User {  type FirstName = string & { __brand: "User:FirstName" }  type LastName = string & { __brand: "User:LastName" }}const firstName = <User.FirstName>"Bob"const lastName = <User.LastName>"Alice"const user: User = {  FirstName: firstName,  LastName: lastName,}

In .tsx files: use "Bob" as User.FirstName and "Alice" as User.LastName

Exposing an interface's default type params

It's currently not possible in TypeScript to have partial type params, you either need to provide none or all of them. However, here is a way you can make it easier to access the default type params of an interface you have declared:

// example.tsinterface Foo<  T = Foo.T,  V = Foo.V,  S = Foo.S<T>,> {  /** property types here */}declare namespace Foo {  type T = string  type V = string  type S<T> = { t: T, something: string }}const foo: Foo<  Foo.T,  Foo.V,  Foo.S<Foo.T>> = {}

Scoped types in object literals

Sometimes we define object literals which may contain some methods. To prevent polluting the module scope with types because naming things is hard, even more if there is already an existing type with the same name. e.g: how common is Callback we could use ambient namespaces:

// example.tsconst foo = <const>{  trigger(cb: foo.Callback): void { }}declare namespace foo {  interface Callback {    (value: string): void  }}const myCallback: foo.Callback = (value: string): void => {  return void console.log(value)}foo.trigger(myCallback)

This also applies to classes, enums, and functions.

Conclusion

  • namespaces allow accessing its exported types and values using dot-notation
  • ambient namespaces are fully erasable types (do not emit code)
  • namespaces and ambient namespaces can be merged with other declarations in the same scope such as type aliases, interfaces, object literals, classes, enums, functions, and even other namespaces
  • ambient namespaces are useful for organizing or scoping types

More


Original Link: https://dev.to/eddyw/typescript-namespace-declaration-merging-for-organizing-types-55o2

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To