# Introducing types to JS without type annotations

**URL:** <https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [August 6, 2020, 6:52am UTC](https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419 "2020-08-06T06:52:00Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jithujoshyjy](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jithujoshyjy/32/399_2.png) [@jithujoshyjy](https://es.discourse.group/u/jithujoshyjy)\
**Post date:** [August 6, 2020, 6:52am UTC](https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419/1 "2020-08-06T06:52:00Z")

</div>

## Type Preservation vs Type Annotation

I know this idea is crazy but it feels wonderful.  
In the majority of languages we use type annotations to declare the type of an identifier.  
Eg:- In TypeScript

```javascript
let day: string = "monday";

```

Eg:- C/C++

```javascript
int day = 2;

```

But there are several problems with this approach.

- As the program grows, the code becomes more verbose.
- The language becomes rigid; JavaScript is an extremely flexible language, A type system with type annotation will reduce its flexibility.
- Increases development time.

## What is Type Preservation ??

It just means that we preserve the type of a variable/identifier.  
i.e, if a variable is initialized with an integer, then that variable can only hold integer values.

_Experimental Syntax:_

```javascript
//Variables
let <day> = "monday";
     day = "sunday"; //Ok
     day = 3; //Error

//Functions
function <planet>(<name> = "") {
   return name + "";
}
planet("Earth") //Earth
planet("Mars") //Mars
planet(100) //Error

//Objects
let farm = {
<owner>: "Deadpool",
<animals>: ["dog", "cat", "cow"],
<number>: [1, 2, 3],
<total>: 6
}
farm.owner = "Hulk"; //Ok
farm.animals.push("fish"); //Ok
farm.animals.push(true); //Error
farm.total = "7"; //Error

```

Looks cool right??  
Without sacrificing too many stuff we have achieved static typing!!  
This idea is not perfect in any means. Please help me improve it further.

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [August 6, 2020, 4:50pm UTC](https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419/2 "2020-08-06T16:50:15Z")

</div>

What's an "integer"? JS only has Number and BigInt.

What if a variable happens to hold a Promise, but the intention is for it to merely hold a thenable?

---

<div class="post-metadata">

**Author:** ![jithujoshyjy](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jithujoshyjy/32/399_2.png) [@jithujoshyjy](https://es.discourse.group/u/jithujoshyjy)\
**Post date:** [August 7, 2020, 5:11am UTC](https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419/3 "2020-08-07T05:11:03Z")

</div>

Sorry Number it is, that was a mistake!!  
(I was thinking in terms of other typed language, my bad!)  
As for the promises what will happen when we assign them to a variable at present?? The same is going to happen if the type preservation is applied. This proposal is not changing anything in the current language. But aims to provide developers a means to exercise control over typing of identifiers.  
It's as safe as private class fields. Nothing will break with its inclusion.

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [August 7, 2020, 4:06pm UTC](https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419/4 "2020-08-07T16:06:30Z")

</div>

I realize that this would be opt-in, which is fine. It seems like the "type" being preserved is inferred - and what I'm asking is, what happens when the type i _want_ the variable constrained to is not an exact match to what gets inferred? (for example, i assign a Promise but want "thenables", or I assign a plain object but want "a specific interface this object provides")

---

<div class="post-metadata">

**Author:** ![jithujoshyjy](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jithujoshyjy/32/399_2.png) [@jithujoshyjy](https://es.discourse.group/u/jithujoshyjy)\
**Post date:** [August 8, 2020, 6:39am UTC](https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419/5 "2020-08-08T06:39:56Z")

</div>

### Reply

You're right!! The type is inferred by the compiler at the initialisation of the identifier, saving the developer from manually asserting the type.

A value assigned to a variable must evaluate to be a primitive(that's how the typeof operator works!!)  
Promise is an _instanceof_ Object, here object is the primitive type(i.e, _typeof_ Promise === "object" ), therefore the variable can only hold objects.  
Eg:-

```javascript
let <regex> = new RegExp("(she|he)llo");
//regex is reserved for objects but not specifically for the instance RegExp.
     regex = {} //perfectly valid

```

If preferred by the language developers, variable preserved for specific object instances can also be implemented.  
My suggestion:

```javascript
let <regex instanceof RegExp> = new RegExp("(she|he)llo");
//or
let <regex in RegExp> = new RegExp("(she|he)llo");
//or
let <regex of RegExp> = new RegExp("(she|he)llo");

    regex = {}; //Error

```

Variables with object instance preservation can be done likewise by giving a new meaning to any of the membership operators mentioned above within the angle brackets.

- _instanceof_ is much more readable.
- _in_ is much more concise.
- _of_ can also be considered.

However, my initial suggestion is to implement the variable preservation for primitive types only.  
The object instance preservation can be set aside for later consideration.  
The reason I say this is because:

```javascript
let <greet in String>;
    greet = "hello";

```

Does this behavior be endorsed??

- We should decide whether greet can only hold an object of instance String or a primitive string.
- what will happen if:

```javascript
	let <greet String>;
	console.log(greet);//undefined or ""

```

These decisions along with others should be considered only after rigorous discussions.  
The discussion on implementation details is the concern of language implementers. Not the scope of my concern.

* * *

This however is an experimental syntax and should be treated as such. Therefore, the syntax should't be taken into account for the evaluation. The idea of variable preservation should be the focus.

A valid concern that I raise is that the current syntax might cause some problems with compiler like Babel, Harp, or Svelte, because they use the angle brackets extensively(like in JSX). Therefore the syntax shouldn't be considered.

In my proposal, type preservation of identifiers works in relation to the **typeof** operator(which of course has some pitfalls). @Ijharb, your suggestion is that it should also take instancing of objects in consideration(relating the **instanceof** operator). As I said earlier, the details should be dealt with the language implementers(i.e, if this feature is ever introduced to the language).

### Conclusion

This idea has never been introduced to any other language. If JavaScript implements this feature, it will be the first to introduce a revolutionary way of type setting identifiers, and also it will prove to the world that an eighteen year old can make a difference...

---

<div class="post-metadata">

**Author:** ![ptomato](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ptomato/32/214_2.png) [@ptomato](https://es.discourse.group/u/ptomato)\
**Post date:** [August 12, 2020, 8:47pm UTC](https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419/6 "2020-08-12T20:47:22Z")

</div>

> [@jithujoshyjy](#):
>
> it will prove to the world that an eighteen year old can make a difference...

Certainly, an 18 year old can make a difference! Regardless of type inference 😄

---

<div class="post-metadata">

**Author:** ![JackWorks](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jackworks/32/260_2.png) [@JackWorks](https://es.discourse.group/u/JackWorks)\
**Post date:** [August 24, 2020, 9:11am UTC](https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419/7 "2020-08-24T09:11:35Z")

</div>

instaceof in JS does not reliable. If you gets an array from another web page it doesn't "instance of" Array in this page.  
It seems like your solution is based on the call structure of the objects.

What if I want to represent a union type?

---

<div class="post-metadata">

**Author:** ![CrazyPython](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/crazypython/32/422_2.png) [@CrazyPython](https://es.discourse.group/u/CrazyPython)\
**Post date:** [August 31, 2020, 11:45pm UTC](https://es.discourse.group/t/introducing-types-to-js-without-type-annotations/419/8 "2020-08-31T23:45:55Z")

</div>

Perhaps in the place of the type annotation is a function. Every assignment leads to the function being called with a single argument, the value on the right hand side that was assigned. Returning false would throw an exception. Returning true would lead to the assignment succeed.

Implementations could assume that returning false is unusual and optimize for the true case.

```javascript
function notnull(v) {
  return v !== null;
}

```

```javascript
let <foo nonnull> = "test";
foo = "hi"; // ok
foo = null; // throws an exception

```

If we want implicit checking: the prototype of the value assigned can have a property `@@assign`, which is read to become the assignment-checking function. For performance, the function would be bound to the declaration and not changeable.

```javascript
let <regex> = new RegExp("(she|he)llo");

```
