Reader small image

You're reading from  TypeScript 4 Design Patterns and Best Practices

Product typeBook
Published inSep 2021
Reading LevelIntermediate
PublisherPackt
ISBN-139781800563421
Edition1st Edition
Right arrow
Author (1)
 Theofanis Despoudis
Theofanis Despoudis
author image
Theofanis Despoudis

Theo Despoudis lives in Ireland, where he works as a Software Engineer for WP Engine and as a part-time tech practitioner for Fixate. He is the co-author of The React Workshop and Advanced Go Programming in 7 Days, Dzone Core Member, and maintains some open source projects on GitHub. Theo is available for conference talks, independent consulting, and corporate training services opportunities.
Read more about Theofanis Despoudis

Right arrow

Chapter 8: Developing Modern and Robust TypeScript Applications

So far in this book, we have focused on learning about the classical design patterns and expanded our exploration with functional and reactive programming methodologies. In the last two chapters of this book, we will switch gears and focus on understanding the best practices and recommendations for developing real-world TypeScript applications.

In this chapter, we begin by demonstrating some of the reasonable combinations of design patterns that you can consider so that you can get the best of both worlds. Next, we will also gain a considerable understanding of how to use the existing utility types and functions that TypeScript exposes over the built-in type definitions. Those utility types are there to help us annotate our models with commonly used types. We will next see an introduction to Domain-Driven Design (DDD) with TypeScript, which is a way to think about and design programming systems using a domain model...

Technical requirements

Combining patterns

It's perfectly fine to combine design patterns as long as they do not interfere with one another or to eliminate any concerns. Doing so, you gain the benefits of both patterns while removing the need to write extraneous and sparse code that you may have when you create many abstractions.

We will showcase some examples of valid combinations of design patterns together with their usage.

Singleton

Singleton is the most flexible pattern to glue on. This is because the traits and benefits it offers usually do not interfere with other patterns and their responsibilities. Quite often, this pattern is implemented using TypeScript decorator syntax or by simply inheriting from the Singleton class.

We will discuss some of the most common patterns that pair well with Singleton:

  • Builder: The Builder object is usually a single instance and should only be used for creating a new object. However, before each use, the client should reset the Builder object...

Using utility types

TypeScript comes bundled with several utility types to facilitate common type transformations. Almost any time you want to define types and interfaces, you also want to consider whether it's better to apply them together or create custom types to enforce some constraints.

Let's take a look at some examples. Imagine that you define a model for a User type that represents a database entity. You would normally define a type like this:

Utilities.ts

 type Address = {
    streetNum: number;
    town: string;
    streetName: string;
  }
  type User = {
    name: string;
    email: string;
    address: Address;
  }
  function loginUser(user: User, password: string) {
      // perform login
  }

Initially, this may work, but later on, you might want to make...

Using domain-driven design

DDD represents an approach to software development that allows us to translate complex domain business logic into software components that match their meaning and purpose. It's a way that we can design applications that speak the same language as the problems they are solving.

The core focus of DDD circles around answering questions such as how do you organize business logic? or how can you manage complexity when the application grows over time? Those are valid questions, and the answers are not definite.

A central pattern in DDD is the bounded context. This is a concept that represents a logical boundary between the separate sub-domains of the organization. Think of it as boxes that contain all the information on a particular domain, such as the user authentication domain, the logistics domain, and the shopping cart domain. For example, in a shopping cart domain, the relevant entities are Cart, Cart Item, Shipping, Price, Adjustment, and so on...

Applying the SOLID principles

SOLID is an acronym for the first five Object Oriented Priniciple (OOP) design principles: single responsibility principle, open-closed principle, Liskov substitution principle, interface segregation principle, and dependency inversion principle coined by Robert C. Martin in his 2000 paper Design Principles and Design Patterns, available at https://fi.ort.edu.uy/innovaportal/file/2032/1/design_principles.pdf.

These principles exhibit a strong correlation with OOP languages and how to structure your programs with maintenance and extensibility in mind. Adopting these practices can contribute to producing code that is easier to refactor and to reason about.

To start with, we'll take a deep dive into these principles with some representative examples in TypeScript, and we will then make some conclusions.

Understanding the single-responsibility principle

A class should have one, and only one, reason to change.

– Robert C. Martin

...

Summary

In this chapter, we provided a list of recommendations and best practices when developing large-scale TypeScript applications. Those practices stem from a combination of experience, traditional patterns, industry best practices, and modern recommended architectural practices.

Making use of multiple design patterns makes those abstractions more flexible and dynamic in nature. Utility types provide several common and very useful type transformations to avoid code duplication when writing types. Understanding when and how to use DDD offers a robust architectural approach for how to design software applications. Finally, leveraging the concepts of the SOLID principles can help create easier software designs to understand, maintain, and extend when implemented correctly.

The next, and concluding, chapter takes a look at the most important caveats and gotchas when developing applications in TypeScript. Collectively with what you learned in this chapter, you will learn how to...

Q&A

  1. What are the benefits of combining design patterns?

    When you combine design patterns, you generally want to use the best traits of each pattern. For example, you may leverage the Singleton pattern with any other pattern that needs to exist only once in the application life cycle. In other cases, you want to leverage their similarities, for example, with the Observer and Mediator patterns.

  2. What is the difference between the Omit and Pick utility types?

    Omit<U, T> lets you pick all properties from the existing type U and then remove the specified keys of type T. It will create a new type consisting of omitted properties T from type U.

    Pick<U, T>, on the other hand, does the opposite. You specify the parameters you want to extract from type U without checking for any relationship with type T. It will create a new type consisting of the selected properties T of type U.

  3. How is DRY different from SOLID?

    Both are basic engineering principles. With DRY, you avoid...

Further reading

lock icon
The rest of the chapter is locked
You have been reading a chapter from
TypeScript 4 Design Patterns and Best Practices
Published in: Sep 2021Publisher: PacktISBN-13: 9781800563421
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Theofanis Despoudis

Theo Despoudis lives in Ireland, where he works as a Software Engineer for WP Engine and as a part-time tech practitioner for Fixate. He is the co-author of The React Workshop and Advanced Go Programming in 7 Days, Dzone Core Member, and maintains some open source projects on GitHub. Theo is available for conference talks, independent consulting, and corporate training services opportunities.
Read more about Theofanis Despoudis