# Assertions: value, type and instance

**URL:** <https://es.discourse.group/t/assertions-value-type-and-instance/849>\
**Category:** 💡 Ideas\
**Tags:** proposal\
**Created:** [July 11, 2021, 6:34am UTC](https://es.discourse.group/t/assertions-value-type-and-instance/849 "2021-07-11T06:34:28Z")\
**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:** [July 11, 2021, 6:34am UTC](https://es.discourse.group/t/assertions-value-type-and-instance/849/1 "2021-07-11T06:34:28Z")

</div>

We are all familiar with python and nodejs assertions:

_// nodejs_

```javascript
assert(1+1 === 2)
// true but on failure throws AssertionError

```

_# python_

```javascript
assert 1+1 == 2
# same as above

```

This idea expands upon the above concept and looks at assertions in extra detail along with a cooler syntax😉

**warning**

```javascript
A lot of unstable terrain ahead! proceed with caution.

```

### Value Assertions

These are the normal assertions that we are all familiar from node and python.

```javascript
1 + 1 :: 2 // true
"ecmascript" :: "javascript" // AssertionError
"string" :: typeof "hi" // true

```

The last example is particularly interesting.  
notice that a value assertion cannot begin with a typeof operator; because that's a whole other kind of assertion👇

### Type Assertions

These provide a way for type verification.  
Notice however they follow a particular syntax and remember that they are not meant to provide solid static typing.

```javascript
let x = "JavaScript"
typeof x :: String

let y = String
typeof y :: Object

let z = [1, 2, 3, 4, 5, 6, 7]
typeof z :: [Array(7) Number]

let a = {
	foo: "bar",
	[Symbol("sim")]: 100
}
typeof a :: Object
// or [Object { String: String, Symbol: Number }]
// irrespective of order

typeof null :: null // I don't know, maybe it should be [Object null]

typeof undefined :: undefined

// some other exotic Objects

let b = new Set(1, 2, 3, 4, 5, 6, 7)
typeof b :: [Set(7) Number]

let c = new Map([[0, 1], [2, 3], [4, 5], [6, 7] ])
typeof b :: [Map {Number : Number}]
// or [Map Number] -- typeof keys only
// or [Map {:Number}] -- typeof values only
// or [Map {Number}] -- typeof keys and values

// Functions
typeof greet :: [Function AsyncFunction]
async function greet(word) {
	typeof word :: String
	const greetings = word + " world!"
	typeof greetings :: String
	return greetings
}

// generators
typeof speak :: [Function AsyncGenerator]
// if it's simply a generator then [Function Generator]
async function *speak(firstWord) {
	typeof firstWord :: String
	yield firstWord
	
	const word2 = "Buzz"
	typeof word2 :: String
	yield word2
	
	const word3 = "Zap"
	typeof word3 :: String
	yield word3
	
	const lastWord = "Bye"
	typeof lastWord :: String
	return lastWord
}

class Animate {
	x2 = 0
	y2 = 0
	constructor(x, y) {
		this.x1 = x
		this.y1 = y
		
		typeof this.x1 :: Number
		typeof this.y1 :: Number
		
		typeof this.x2 :: Number
		typeof this.y2 :: Number
		
		typeof this.moveTo :: Function
		// this is trivial any away
	}
	
	moveTo(x2, y2) {
		typeof x2 :: Number
		typeof y2 :: Number
		// do something
		typeof [x2, y2] :: [Array Number]
		return [x2, y2]
	}
}
typeof Animate :: [Function Object]

```

We can take this further and create algebraic types

```javascript
let str = "I'm a String"
typeof str :: String | Number

let sym = Symbol("I'm Invincible")
typeof sym :: !String
// sym can be anything except a String

typeof sym :: !(String | Number)
// means that sym can be anything except a String and a Number

```

The real power of algebraic types can be seen from Arrays and other collection types.

```javascript
typeof [1, "hi", 3, true] :: [Array Number | String | Boolean]

typeof new Map([["a", "apple"], [0, false] ]) :: [Map {Number | String: Number | Boolean}]

```

### Instance Assertions

These assertions are for instance checking

```javascript
instanceof Error :: TypeError // true
instanceof Human :: Person | Mammal // true
instanceof Insect :: Dodo // AssertionError

```

I personally think they are cool and would make JavaScript even cooler!  
What's your take on this idea??

This is a lengthy idea, so there might be some errors, misunderstandings and syntax ambiguities along the way! please care to mention them and help refine this idea!

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [July 11, 2021, 9:15am UTC](https://es.discourse.group/t/assertions-value-type-and-instance/849/2 "2021-07-11T09:15:59Z")

</div>

> [@jithujoshyjy](#):
>
> We can take this further and create algebraic types
> 
> ```javascript
> let str = "I'm a String"
> typeof str :: String | Number
> 
> ```

You may be interested in some of the syntax ideas in [GitHub - tc39/proposal-pattern-matching: Pattern matching syntax for ECMAScript](https://github.com/tc39/proposal-pattern-matching) .

```javascript
match (typeof value) {
  when ('object' | 'function') if (value !== null) { … }
  when ('string' | 'number') { … }
  else { … }
}

```

Maybe this issue: [Builtin matchers for primitives (string | number | boolean | bigint | nullish) · Issue #209 · tc39/proposal-pattern-matching · GitHub](https://github.com/tc39/proposal-pattern-matching/issues/209) too

---

<div class="post-metadata">

**Author:** ![theScottyJam](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/thescottyjam/32/616_2.png) [@theScottyJam](https://es.discourse.group/u/theScottyJam)\
**Post date:** [July 11, 2021, 1:36pm UTC](https://es.discourse.group/t/assertions-value-type-and-instance/849/3 "2021-07-11T13:36:21Z")

</div>

One problem with these types of assertions:

```javascript
typeof myArray :: [Array Number]
typeof myMap :: [Map {Number | String: Number | Boolean}]

```

is there's no efficient way to implement this. You would have to visit every element to check if they are all the correct type.

---

<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:** [July 11, 2021, 2:38pm UTC](https://es.discourse.group/t/assertions-value-type-and-instance/849/4 "2021-07-11T14:38:21Z")

</div>

yes that's very true. It's not meant to be a static typing mechanism. Its purpose is to ensure relative correctness. Correctness costs performance; that's an obvious thing in dynamic languages(I'm quoting Python and TS here 😏).  
This idea will surely help in unit tests ;)  
Assertions usually cost something but it's usually worth it!  
I'm no expert but I sure believe that the browser vendors might find a way to optimise it; (They usually does, right??)

---

<div class="post-metadata">

**Author:** ![Jonas\_Wilms](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/jonas_wilms/32/189_2.png) [@Jonas\_Wilms](https://es.discourse.group/u/Jonas_Wilms)\
**Post date:** [July 16, 2021, 9:11pm UTC](https://es.discourse.group/t/assertions-value-type-and-instance/849/5 "2021-07-16T21:11:45Z")

</div>

I guess the engine can at least check this more efficiently than userland code (e.g. ElementKind arrays in V8).

I currently write a lot of code in languages that do have explicit assertion syntax and semantics, and I must say that this is something that I'm missing in JS.

I'm a bit sceptical concerning the proposed syntax I'd rather prefer something like

```javascript
assert hopefullyArray instanceof Array;
assert typeof hopefullyString === "string";

```

---

<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:** [July 17, 2021, 5:28am UTC](https://es.discourse.group/t/assertions-value-type-and-instance/849/6 "2021-07-17T05:28:11Z")

</div>

Thanks Jonas;  
I considered the new syntax for a couple of reasons.

- To avoid the undesirable results of typeof & instanceof operators.
- To give us more expressiveness(through the Object toStringTag syntax)
- To support alterations and negations(algebraic types)

This doesn't mean in any way that it's perfect or complete. It's not as powerful / coherent as static typing but still does a good job at documentation and improving correctness.

> [@Jonas\_Wilms](#):
>
> ```javascript
> assert hopefullyArray instanceof Array;
> assert typeof hopefullyString === "string";
> 
> ```

and of course you can do it as:

```javascript
instanceof Array :: hopefullyArray
// or
true :: hopefullyArray instanceof Array

typeof hopefullyString :: String
// or
"string" :: typeof hopefullyString

```

This can be further extended (as mentioned earlier by others) through the pattern matching.

---

<div class="post-metadata">

**Author:** ![ethanlal04](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ethanlal04/32/918_2.png) [@ethanlal04](https://es.discourse.group/u/ethanlal04)\
**Post date:** [July 26, 2021, 2:16pm UTC](https://es.discourse.group/t/assertions-value-type-and-instance/849/7 "2021-07-26T14:16:58Z")

</div>

Hello @jithujoshyjy,

I like your idea, but I think we can do most (not all) assertions with just [JSDocs](https://jsdoc.app/) when `@ts-check` has been enabled.

---

<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:** [July 26, 2021, 2:36pm UTC](https://es.discourse.group/t/assertions-value-type-and-instance/849/8 "2021-07-26T14:36:05Z")

</div>

JSDocs is an annotation mechanism while this is like console.assert() / node assert(); aka an assertion mechanism. I do like JSDocs. It can help in assertions but it is limited to comments and hence not very interactable through code.  
(spoiler: I just wanted a little haskell in JS😉)
