*It’s time for one of the most useless things I ever made — something beyond reason, where the logic stops being rational and the void is the reality. It’s time to create a calculator using only types from Typescript.*

A few days ago, I remembered a discussion with a friend about Turing-complete systems. We checked Wikipedia article on the subject, and we discovered that many things (like games) were Turing-complete. So yes, Minecraft is Turing-complete, Factorio too, Dwarf Fortress too, and it seems that Habbo Hotel and Magic: The Gathering (yes, the cards game) are also Turing-complete.

We also found somewhere that the type system of Typescript is Turing-complete. With this knowledge, I decided to start developing something that would not change anything: a calculator with only Typescript types.

Yes. This is one of the most stupid ideas I got for a while. But this is a fun exercise you can do to prove your skills in typing everything.

## The rules

If you want to try to do the calculator, here are the rules of the “game” (if we can call this a game):

- you have to start with only two types:
`BZero`

(for Boolean Zero) and`BOne`

(for Boolean One).

- you can only use types. No interface, no enum, only types.
- you have to compute the four basic mathematical operations (with types): add, subtract, multiply and divide. You can also add modulo.
- this code should works:

Due to the way I implement the calculator, I use another type `Result`

to read the result:

This type is totally optional in the rules. But you must have a exact number type at the end of the computation. For example, you should have:

And here you go! It’s time for you to code!

…

…

…

Yeah, better read the solution, isn’t it?

## The solution

### Conception

Firstly, I search what the ways to get a number type from a type in Typescript are. You have your base operation to transform `BZero`

and `BOne`

to `Zero`

and `One`

number if you know this.

I tried something based on array indexes, but there was no way to get a number. So I discovered that Typescript tuples have a `length`

property. And it works with variable tuples since 3.0. With this information, I began to write a calculator based on Tuples.

The first types we need are the `Zero`

and the `One`

based on tuples. In this way, I write a simple conditional type that returns a tuple with the number of elements equivalent to the number it describes. For example :

In this way, we need a type to read the length of the tuple to get the desired type number.

### Operation 1 : Add

With this conception, the `Add`

type is the most straightforward operation to implement, thanks to Typescript 4.0. We have to concatenate the two tuples, and we have done an `Add`

type.

### Operation 2 : Subtract

#### The hard way

Now, the fun begins.

We need to think about the computation behind the subtraction. So let’s come back to elementary school.

I have 6 balloons. I give 4 balloons to Manu. I now have 2 balloons remaining.

In terms of tuples, we can illustrate the problem with this :

To implement the subtraction, I take each element of `MyBalloons`

one by one and check if each element exists in `NewManuBalloons`

. When I arrive at the moment there’s no more element in `NewManuBallooons`

, I start to increment a variable which will be the result.

But there’s a problem: it looks like a loop. How can we achieve a loop in Typescript?

The answer here is to use a recursive type. And with a condition, we can do that with a recursive conditional type. Here’s the code:

Oh yeah, there’s another tip: I use
type inference to remove elements of a tuple. For example, if I have `type A = [true, true, true]`

, I will get `type H = [true, true]`

. This is because I check if `A`

’s first element is a boolean, and I send the rest of the tuple in another type variable.

I use the type inference in a second condition to check if the current element exists in `B`

. When there’s an element in `A`

and `B`

, I recall the `Subtract`

type with the remaining elements of `A`

(`H`

) and the remaining elements of `B`

(`J`

). If there’s no more element in `B`

, we continue to call `Subtract`

, but we increase `Res`

at each call. And when `A`

is empty, we return `Res`

type.

And now, we have a subtraction with only types. Note that this subtraction only works with positive integers. This problem is caused by tuples, because yes, you cannot have a tuple with a negative length.

#### The smart way

The hard way is a pure example of overengineering. Because there’s such a simple method to do a subtraction: subtract `B`

from `A`

and keep the result.

For my defense, I understood that I could use type inference between 2 dynamic types when working on `Divide`

. But you can shame me, and it’s okay.

Here’s the code:

### Operation 3 : Multiply

We already have seen all the techniques we need to Multiply. So we need to add `B`

times the `A`

number. This is now a piece of cake since the subtraction’s hard way.

To multiply, make a loop (with recursive types). In this loop, remove `One`

from `B`

, add `A`

to the result, and send the `Res`

when `B`

is Zero. In this way, we will add `A`

`B`

-times, so we are doing `A`

x `B`

.

### Operation 4 : Divide

We have worked since the beginning with integers. So we can only have a Euclidian division for this part.

In the subtraction, we search if `A`

can contain `B`

and what’s remaining. We will do the same thing, except we need to search how many times `A`

contains `B`

. So we have the same primary condition as the subtraction, but we add a recursive type with an incremented result at each loop iteration. When `A`

cannot contain `B`

anymore, send the number of loops done until here.

### Operation Bonus : Modulo

Modulo is almost the same as the Divide. We keep checking how many times `A`

contains `B`

, and when we reach the end, we return the remaining value instead of the number of iterations. And tadaaaaaa, we get the modulo operation.

So here we have a working calculator with only Typescript types. I thought about implementing the decimal calculator based on the binary representation of decimals. But this is clearly madness. I hope you enjoy reading this piece of programming like I enjoyed writing it. And last but not least, here’s the topic of the initial discussion I had with my friend about Turing-Complete Typescript.

Thanks for reading! From all of us here, I want to wish you happy programming and God Bless, my friend! :)