Home » Web » TypeScript » How to organize all the model interfaces and types in your TypeScript project

How to organize all the model interfaces and types in your TypeScript project

So many ways, so many good solutions. I do not think you can go very wrong regardless of the approach employed with your types. However, there are some benefits in few patterns that I prefer. As a rule of thumb, I do not want to search far away from my types. While the tool that you are using might provide a shortcut to search by name easily, and I do leverage it most of the time, it is crucial to find types easily when you do not know the name or when you are not sure if it already exists. The reason is mostly to avoid duplication and to ease the introduction of new developers in your project but also to find out if one of your teammates already coded a definition that you could reuse.

First of all, the approach I am using is subjective. It means that you have to take many choices that some people might or not agree with your team. I have worked in systems where all the components (views) were together, and all the test in one folder, and all the model in one folder. This is straightforward but come with the cost that when your application grows that these folders are neverending. It becomes hard to navigate. I also saw folder divided by team, which is okay until organization breakdown the structure and then it becomes a mess. I also seen some separation that works by model but mix all model files are a sibling to your views (in React your .tsx file, in Angular the .html), to your tests, etc. The approach is not bad, but when you start having more than one component or page using the same model you are stuck.

The approach I recommend is to have your source folder divided by domain of business. For example, under your “source” folder, you can have a “UserManagement”, a “Products”, an “Inventory”, a “Shipping” folder etc. The idea is at that point, you do not rely on the technology that you will use, neither how your application will separate the UI. Your user management might have 1 page or 10 pages, it doesn’t matter. The choice of these domains is subjective. You could avoid having “Inventory” and put everything under “Products”. It is up to you and your team to figure out how fined grained your want these domain folders.

Under each of these domain folders, you can start bringing some specification of your technologies. For example, with React, each of these folder has a “Actions”, “ContainerComponents”, “Middlewares”, “Models”, “PresentationComponents” and “Reducers”. Once again, you have some freedom. You can keep all your container and presentation into a single “components” folder. I like to divide them because I know that my containers are connected while my presentations are more reusable and not connected to Redux directly. Within each of these folders, I have my Typescript file (.ts or .tsx) as well as my tests. For a long time, I positioned my tests files as a sibling of the source folder, but having them close to the files they are testing is a way to keep them in sight. Because they are always in view, I tend to test more. I also clearly see if a file is not having a test file.

Some types are cross domains. Shared types are also valid for very generic visual components. In that case, I have at the root, inside the source folder a domain called “shared.” The cross-domain folder is the one that every domain folder can access. Having a shared folder require to be diligent. It is easy to insert code random code instead of thinking where to locate the file accurately.

If we come back to the type, each domain folder has a model folder which has many files. The separation is not one type, one file. The reason is that it would become uncontrollable. The number of types grows very fast, and it is not rare to have thousands of types, even for a small product. The idea is to divide the file per main entity. For example, a product (interface Product) can have a product category (Interface ProductCategory) and a ProductSize (enum ProductSize). These three types can be in the “Product.ts” file. Again, there is room for subjectivity. Someone could argue that more or less type can be in or out of a file. The important here is to have something that makes sense. I often like to have the main entity, in that case, “Product” to hold every children class, interface, enum, type in the same file. I like having a mapping file “ProductMapping.ts” that manipulate the entity from a normalized structure to a denormalized for example.

At the end of the day, the most important detail is to stay coherent. The overall goal is to find where are a type without searching for a long time.

If you like my article, think to buy my annual book, professionally edited by a proofreader. directly from me or on Amazon. I also wrote a TypeScript book called Holistic TypeScript

11 Responses so far.

  1. Geewee says:

    Just wanted to let you know the contrast of your fonts is way off. The text is way too light – it’s basically impossible to read.

    • The contrast ratio of the foreground (gray #828282) and background (white) is 3.84:1. This does not passes the WCAG 2 level AA which requires a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text, but not by far.

      From that metric, I would say that “impossible” is a stretch. Maybe there is something else that is not loading for you and the color of the foreground and background are not loaded properly. What device are you using (and which browser)?

      • flafik says:

        I use Win 10 Firefox/Chrome and it is barely readable, too light.

        • Okay, I tested with Win 10/Chrome and MacOs/Chrome. I am using a pre-baked theme… I can find a way to increase the contrast. Meanwhile, can you send me a screenshot? I am curious how it looks on your side. Thank you in advance

          • flafik says:

            screenshot from firefox, chrome looks the same https://ibb.co/eEz9Lq

          • Thank you for the screenshot. This is also what I see.

            I do not believe it’s hard to see, but this is a personal preference. As mentioned, the ratio is at 3.84:1 which is not that bad and this is probably the reason the WordPress’ theme is using it.

            Nevertheless, I hear you. It can be annoying and I will figure out how to increase to a darker gray in a short future. Thank you for taking your time to improve my blog. I appreciate.

          • I modified the color to be at a contrast of 7.34. Can you tell me if it is more readable for you?

          • flafik says:

            Yes, it is better. Now I can read it quite comfortly. It might be just my monitor, which is quite old TN panel and colors might look differently. If I look on the screenshot on my phone it looks better. Thank you for your time.

    • SafariGuy says:

      You can use Safari reader view for better readability.

    • Can you send me a screenshot please? I would like to see what you see 🙂

  2. Krzysztof Grzybek says:

    Nice! Thanks for sharing 😉

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.