Union Type & Literal Type By albro

in Programming & Dev2 months ago

Union Type & Literal Type

Another very interesting types in typescript are union types. This type of data is usually a combination of two or more of the previous types. Let me explain with an example:

function combine (input1: number, input2: number) {
  const result = input1 + input2;
  return result;
}

I want to edit this function to work with both numbers and strings. That is, if it receives a number, it will add them mathematically, and if it receives a string, it will concatenate them. The problem is that currently this function only accepts numbers. For example:

const combinedAges = combine(30, 26);
console.log(combinedAges);

If we do this, we will have no problem and the result 56 will be displayed in the console of our browser, but if we try to add two strings together, Typescript will give us an error:

const combinedNames = combine('Max', 'Anna');
console.log(combinedNames);

Such a code is not allowed because above we have typed numbers as entries. If we go back and put this type as string, the code above will be error, but the code before adding the numbers will encounter an error. This is where union types come in and allow us to define a type that is the sum of numbers and strings. For example, to determine the type of parameters of the combine function, we can say:

function combine(input1: number | string, input2: number | string) {
  const result = input1 + input2;
  return result;
}

The symbol between number and string is known as pipe, which is a vertical line. In addition, there is no limit to using two types and you can add as many types as you want to the function with the above structure. Now, as soon as you do this, you will get an error and TypeScript will tell you that the + operator is not used to type a number and a string at the same time. As you know, the appearance of this word is wrong and we can use this operator for numbers and strings. Typescript only looks to see what your type is and when it realizes that it is a union type, it doesn't check inside it anymore. In fact, TypeScript tells you that you should write more specific code for such cases, so we do the same:

function combine(input1: number | string, input2: number | string) {
  let result;
  if (typeof input1 === 'number' && typeof input2 === 'number') {
    result = input1 + input2;
  } else {
    result = input1.toString() + input2.toString();
  }
  return result;
}

As you know, the typeof operator gives us the type of a variable. Here, using this operator, we have said that if the type of the input parameter is number type, add them, but if it is not, it must be a string, so by using the function toString makes sure that the inputs are converted to strings and then concatenates them.

Now if we have the following code:

const combinedAges = combine(30, 26);
console.log(combinedAges);
const combinedNames = combine('Max', 'Anna');
console.log(combinedNames);

And go to the browser, both codes will run without error:

console.log different inputs

Literal types specify the data itself instead of saying that my parameter or variable must take a specific data type. We have seen something like this before:

const number = 5;

If you move your mouse over this constant, you will see its type as follows:

Fixed type display for consts

That is, the type is no longer "number" but 5, because the value of the constants never changes.

We can use this feature and, for example, make it possible to perform a certain transformation when calling the function based on the input value. Suppose we add a third parameter called resultConversion to the combine function that we defined above, which is of string type:

function combine(input1: number | string, input2: number | string, resultConversion: string) {

I want to make it so that when we call this function we can do something like this:

const combinedAges = combine(30, 26, 'as-number');

In other words, use the third parameter to determine that the first and second parameters are added together as a string or as a number! Of course, you can choose your desired value instead of as-number. I want to check three modes:

const combinedAges = combine(30, 26, 'as-number');
console.log(combinedAges);
const combinedStringAges = combine('30', '26', 'as-number');
console.log(combinedStringAges);
const combinedNames = combine('Max', 'Anna', 'as-text');
console.log(combinedNames);

Once the numbers as numbers, again the strings containing the numbers as numbers and finally the strings as a string. Currently, our function is not ready for such a task, because we have set the third parameter as a string, which means that when calling the function, we can enter any string value in it. I want only as-number and as-text to be acceptable, not any string value.

One way to solve this problem is to say:

function combine(input1: number | string, input2: number | string, resultConversion: string) {
  let result;
  if (typeof input1 === 'number' && typeof input2 === 'number') {
    result = input1 + input2;
  } else {
    result = input1.toString() + input2.toString();
  }
  if (resultConversion === 'as-number') {
    return +result;
  } else {
    return result.toString();
  }
}

That is, if as-number is passed as the third parameter, convert the result into a number. Of course, we get the value 3026 for the combinedStringAges variable, so there is an error in this part.

Another way is as follows:

function combine(input1: number | string, input2: number | string, resultConversion: string) {
  let result;
  if (typeof input1 === 'number' && typeof input2 === 'number' || resultConversion === 'as-number') {
    result = +input1 + +input2;
  } else {
    result = input1.toString() + input2.toString();
  }
  return result;
}

That is, check the value of resultConversion and if it is so, make sure to convert the inputs to numbers with the + sign (even if they are strings). Now the correct values ​​of 56, 56 and MaxAnna are displayed in the browser console respectively.

Even though we are given the correct values, our function is still not a good function because type is the third parameter of the string, so we can type anything in it. For example, let's forget and type as-text as_text. So instead of saving these items, we have to do something else because we may have dozens of items like this.

This is where literal types along with union types come to our aid:

function combine(
  input1: number | string,
  input2: number | string,
  resultConversion: 'as-number' | 'as-text'
) {
  let result;
  if (typeof input1 === 'number' && typeof input2 === 'number' || resultConversion === 'as-number') {
    result = +input1 + +input2;
  } else {
    result = input1.toString() + input2.toString();
  }
  return result;
}

If we determine only two values ​​for the third parameter, our problem will be solved! Note that I have written the parameters of the function in different lines to make them more readable, and then I have specified two literal types, and there has been no special change. Now, if you type anything other than these two, you'll get an error, so we'll make sure we don't make a mistake.

Sort:  

Congratulations!


You have obtained a vote from CHESS BROTHERS PROJECT

✅ Good job. Your post has been appreciated and has received support from CHESS BROTHERS ♔ 💪


♟ We invite you to use our hashtag #chessbrothers and learn more about us.

♟♟ You can also reach us on our Discord server and promote your posts there.

♟♟♟ Consider joining our curation trail so we work as a team and you get rewards automatically.

♞♟ Check out our @chessbrotherspro account to learn about the curation process carried out daily by our team.


🥇 If you want to earn profits with your HP delegation and support our project, we invite you to join the Master Investor plan. Here you can learn how to do it.


Kindly

The CHESS BROTHERS team

Congratulations @albro! You have completed the following achievement on the Hive blockchain And have been rewarded with New badge(s)

You got more than 600 replies.
Your next target is to reach 700 replies.

You can view your badges on your board and compare yourself to others in the Ranking
If you no longer want to receive notifications, reply to this comment with the word STOP

Hello,
this Comment has been upvoted with 100%, thanks to @albro who burned 1000 PLANET
With this burn @albro is actively participating in the CLEAN PLANET reward protocol.
@albro is helping @cleanplanet to grow with the curation.
Thanks for your help
@cleanplanet

Thanks for your contribution to the STEMsocial community. Feel free to join us on discord to get to know the rest of us!

Please consider delegating to the @stemsocial account (85% of the curation rewards are returned).

You may also include @stemsocial as a beneficiary of the rewards of this post to get a stronger support.