Reflecting business logic rules into the domain models using typescript — Part 2

Mohsen Sareminia
ITNEXT
Published in
3 min readAug 2, 2020

--

Reflecting business logic rules into the domain models

In the previous article, we learned how to create self-documented types and models. but they were just types and didn't have any functionality.

In this article, we are going to write some code that creates and validates those types.

At the end of this article, our types can be used in real-life projects.

The project source code is available here:

Bootstrap

First, we need a typescript project. so let's create it.

yarn init -y
yarn add --dev typescript ts-node
./node_modules/.bin/tsc --init

Then we create our types.

String50

At the top, there is the type declaration. after that, there is the makeString50 function. this function accepts any argument and tries to create String50 .

It checks if the argument type is a string and its length is less than 50.

If the argument doesn't satisfy the rules and constraint it will throw a CustomTypeError exception.

And here is CustomTypeError

It is just a simple class for showing errors.

We use it in try catch blocks to handle our custom type errors.

Let's continue to define other types.

Email

We used a regex to verify the argument is really an Email.

PostalCode

Just like the Email. using a regex to verify.

EmailAndPostalCode

First, we check if the argument is provided. then we use Email and PostalCode types to do the verifications.

ContactInfo

The ContactInfo type is a union type. it could be Email or PostalCode or both of them.

in makeContactInfo function, first we try to make an Email , then try to make a PostalCode and finally, we try to make EmailAndPostalCode .

If all of them fail, then the exception will throw.

Now we have all types we want and can create the Person model.

Person

In makePerson function all we need to do is call the type maker functions.

If all of them return a validated value, we create our person model.

Let's create persons using makePerson function and test what we created.

The createAndLogPerson function only try to create a person and print the value. if it fails it will print the error.

Let's see the output:

  • person 1 is valid and has email for contact info
  • person 2 is valid and has postal code for contact info
  • person 3 is valid and has both email and postal code for contact info
  • person 4 is not valid because it does not have anything for contact info. so it will throw an error
  • person 5 is not valid because it has the email for contact info, but it is not a correct email format. so it will throw an error

In this article, we make our types actually work and validate the input data.

But as you can see it is a boring job to do.

First, we need to declare the type and then we should write some function to make and validate it. And this type of structure for our models only makes sense in our domain and in our projects. What if we need to send this data to someone else. for example, what if we need to return this data as the response of a rest API call?

We need another function to get Person as the argument and return a normal structure for it like:

{
"firstName": "pf1",
"lastName": "pl1",
"email": "pf1@gmail.com",
"postalCode": "3483848392",
}

We need to define something like encodePerson function.

As you can we have to createmake... and encode... functions for every type.

We need some way to automate these functions.

Fortunately, there is a library for typescript to do just that. You can read about it here:

In the next article, we are going to create and validate our models using io-ts library.

Continue to the next article.

--

--