Types of repetition in type script: a short exploration

by SkillAiNest

This is called There are two different worlds in the type script that are present: the kind of world and a world of value.

Consider this line of code:

const firstName: string = 'Maynard';

While firstName And 'Maynard' Live in a world of value, string Belongs to the kind of world.

Or, consider it typeof The operator, which is in both worlds.

Here is in the world of value:

console.log(typeof 42); 

And, here is in the type of world, which is used to extract the type of function incrementWhich then moves The type of utility that is called ReturnType:

function increment(n: number)  null;
  right: TreeNode 

type T = ReturnType<typeof increment>; 

One of the wonders of the world is the existence of repetitive types. They are similar to some of the repetitive functions that you are already aware of.

Here is a repeated walking function:

function addUpTo(n: number): number  null;

And, here’s a repetition type:

type JSONValue =
  | string
  | number
  | boolean
  | null
  | 
  value: T;
  left: TreeNode ;

Function addUpTo Calls itself, each time with its low price nSlowly reaching the base case. For,,,,,,,,,, for,, for,,,, for,,,, for,,, for,,,, for,,,, for,,,, for,,, for,,, for,,, for,,, for,,,, for,,, for,,, for,,,, for,,, for,,,, for,,, for,,, for,,,, for,,, for,,, for,,,, for,,, for,,,, for,,, for,,,, for,,, for,,,, for,,, for,,,, for,,,, for,,,, for,,,, for,,,, for,,,, for,,,, for,,, for,,, for,,, for,,, for,,,,, for,,,, for,,,, for,,,, for,, for,.n Assumed that this is an irrational number, otherwise, we will have Maximum call stack size exceeded Mistake.)

Brand JSONValue Is the type of union that has one Index Signature In a possible type of it (
value: T;
next: LinkedList
), And value itself is a reference.

To see it with an instance, we say we have something person It has features nameFor, for, for,. ageAnd friends:

const person = {
  name: 'Alice',
  age: 25,
  friends: 
  value: T;
  next: LinkedList 
};

Value friends There is a item that has numbers as its characteristics, the value of each one that looks like a person we have just appreciated. So, we can form A Person Type for this where the value is friends Is an item that also has a variety of value Person:

type Person = 
  value: T;
  left: TreeNode ;

Note: In the JavaScript, the keys to the objects are either wire or symbol. Even if we explain key As a numberJavascript will eventually force the keys to the wire objects.

In this article, we will not only take a look at what types of repetition are in the type script, but we will also see how they can apply on the data structure and how they can be useful in two different cases of use.

This can prove to be a great tool for a very specific situation in your toolkit, such as when you need to enhance an utility type or get a “internal” type of multi -dimensional array.

Let’s start your search.

Here’s what we will cover is:

  1. Types of repetition for trees and connected lists

  2. Repeat with map -up and conditional types

  3. Use cases for types of repetition

  4. Result (and a warning!)

Types of repetition for trees and connected lists

Remembering types may be considered better with a tree -like data structure:

A binary tree where the root node has two children, left and right. The left child has left and right children, each of them has their own left and right children. Root node's right baby is left -handed baby, and a right baby who is a leaf node.

For example, a node of the binary tree is at least two children, left and right. A child node, if it also has children, is the root of a sub -tree.

We can make a TreeNode Type for a binary tree:

type TreeNode =  null;
;

This is a common type, so value There may be any kind that we move to it. left And right Children can also be TreeNode Himself or null.

We say we have this binary tree:

A binary tree, which costs 8, has a root node. He has a left -handed child priced at 3 and right child cost 10. The left child has a node of the left baby, which is priced at 1 and the node of the right baby, which costs 6, which is priced 4 and the node of the right baby, which costs 7. The right baby's right baby is priced at 10, which costs 14, which costs 14, which costs 14.

We can represent her like it, with its type TreeNode Which we have just appreciated:

const binaryTree: TreeNode<number> = {
  value: 8,
  left: {
    value: 3,
    left:  null;
,
    right: {
      value: 6,
      left: 
  value: T;
  next: LinkedList ,
      right: {
        value: 7,
        left: null,
        right: null
      }
    }
  },
  right: {
    value: 10,
    left: null,
    right: {
      value: 14,
      left: {
        value: 13,
        left: null,
        right: null
      },
      right: null
    }
  }
};

Since this is a common type, we are undergoing its type number This type is used as value.

Likewise, we can create a type for the LinkedIn list where each node occurs value And a next Property that indicates either another node or null:

type LinkedList = {
  value: T;
  next: LinkedList | null;
};

So, if our attached list looks like this:

A LinkedIn list where the head node is indicated 1, which points to the node with value 2, which points to the node, which is cost 3.

We can represent it with type LinkedList:

const linkedList: LinkedList<number> = {
  value: 1,
  next: {
    value: 2,
    next: {
      value: 3,
      next: null
    }
  }
};

Note: We used the kind of alias in the aforementioned examples, but we can use one interface Instead of:

interface TreeNode {
  value: T;
  left: TreeNode | null;
  right: TreeNode | null;
}

interface LinkedList {
  value: T;
  next: LinkedList | null;
}

Repeat with map -up and conditional types

Applying the repetitive types on the values ​​that represent the data structure are slightly clear and not much interesting, but we can also discover other options where repetition can also be used, such as maps and conditional types.

Mapid types are an easy way to create a new type of new type. We, for example, can create a new category using an item’s keys, where we Map Keep a different value type.

We say we have a colors The object in which the color name and the related hex values ​​are. Are of values string Type, but we say we want to make an item where the keys are the same, except that the values ​​should be the type boolean:

const colors = {
  aquamarine: '#7fffd4',
  black: '#000000',
  blueviolet: '#8a2be2',
  goldenrod: '#daa520',
  indigo: '#4b0082',
  lavender: '#e6e6fa',
  silver: '#c0c0c0'
};

type ColorsToBoolean = {
  (K in keyof T): boolean;
};

type Result = ColorsToBoolean<typeof colors>;

Result Will then look like it:

A screenshot of the code block that is explained above when the type of `results' results. The keys are similar to the colorful objects, and all the values ​​are `Bowlin.

A to make a Repetition Mapid type, however, we need the same type of reference we are making, thus:

type Recursive = {
  (K in keyof T): Recursive;
};

Before leaving more, let’s take a look at the conditional types, which look very similar to the conditional feedback that use the turner operator.

AType extends AnotherType ? ResultTypeIfTrue : ResultTypeIfFalse;

It has this familiar form:

condition ? resultIfTrue : resultIfFalse

Now, we can combine both mapper and conditional types to form a repeated mapped condition:

type Recursive = {
  (K in keyof T): T(K) extends number ? T(K) : Recursive;
};

We make a map on the same type of ancestral type type if it is a numberOtherwise, continue with repetition.

Use cases for types of repetition

Use case 1: DeepPartial

A use of repetitive types is increasing the type of utility type capabilities Partial.

We say we have a type for an article, using a interface This time:

interface IArticle {
  title: string;
  description: string;
  url: string;
  author: {
    name: string;
    age: number;
  };
}

Partial Makes all the features of an item that is optional.

But, if we try to do this:

const article: Partial = {
  title: 'Navigating the Mysteries',
  description:
    'As we walk our questions into a troubled future, storyteller and mythologist Martin Shaw invites us to subvert today’s voices of certainty and do the hard work of opening to mystery.',
  url: 'https://emergencemagazine.org/essay/navigating-the-mysteries',
  author: {
    name: 'Martin Shaw'
  }
};

Our fault would be: Property 'age' is missing in type '{ name: string; }' but required in type '{ name: string; age: number; }'. All properties as expected are optional, except that age Which property is owned author. So, Partial Not going to work for more than one level of depth.

In our example, we don’t want to pass in a age Property for authorSo we need to find a way to work.

In fact, the repetitive meated conditional type we have just described above is a matter of great use for it. We can use repetition so that all features are optional, they do not matter deeper.

type DeepPartial = {
  (K in keyof T)?: T(K) extends object ? DeepPartial : T(K);
};

Now, if we try with our example DeepPartialThere are no mistakes, and the problem is the solution:

const article: DeepPartial = {
  title: 'Navigating the Mysteries',
  description:
    'As we walk our questions into a troubled future, storyteller and mythologist Martin Shaw invites us to subvert today’s voices of certainty and do the hard work of opening to mystery.',
  author: {
    name: 'Martin Shaw'
  }
};

Use case 2: UnwrapArray

Another use of the use that we can take a look is when we need a “internal” type of multi -dimensional row.

Consider this:

type UnwrapArray = A extends Array ? UnwrapArray : A;

We describe a UnwrapArray The usual type if we go through its category is another row (A extends Array), Then it passed UnwrapArray Once again until we reaches a kind of kind that does not extend Array.

Note That we use infer Key word to extract. infer Only used with conditional types when extends Used, so it is best for our purpose.

Now, we can get an internal type:

type Result = UnwrapArray<string()()()>; 

Using keywords Array Will be the same result:

type Result = UnwrapArray<Array<Array<Array<string>>>>; 

Result (and a warning!)

The universe of repetition types of type script is interesting and very powerful. But, of course, there is a great deal of responsibility with great power. Type’s own documents of the type script warn us:

Keep in mind that although these repetitive types are powerful, they should use responsibility and a little. (Source)

Not only is it that repetitive types can result in more time for type checking, but with considerable complexity, it can also result in timely error. In fact, the documents also tell us not to use them at all if possible.

So, was it all that was nothing?

The answer depends on what you make from it. Repeat is a powerful concept that is definitely used in type script as we have seen in this article, and if used responsibly, it can be a great tool.

You may also like

Leave a Comment

At Skillainest, we believe the future belongs to those who embrace AI, upgrade their skills, and stay ahead of the curve.

Get latest news

Subscribe my Newsletter for new blog posts, tips & new photos. Let's stay updated!

@2025 Skillainest.Designed and Developed by Pro