Proposal: Static Typing

# IdkGoodName Vilius (5 years ago)

I am proposing to add static typing to ESNext. There might not be a lot of interpreted languages with static-typing like type checking, but it would be quite interesting to see it in JavaScript. CreatorVilius/Proposal-Static-Typing . Static typing was proposed in ES4, but as ES4 was backwards incompatible, it was cancelled along with static typing. This proposal might be similar, but not the same - it is backwards compatible, since it can be optional(whenever user wants to use it or not).

EDITED

# Andrea Giammarchi (5 years ago)

Just my personal thoughts on this.

The way PHP migrated to types has been thought incremental steps, and it worked pretty well.

Since types have been demanded by the JS community for a while, I think it'd be key to approach JS types not all at once, but through smaller iterations.

As example, a proposal with a whole section entitled "Other useless things" would easily diverge focus to stuff the is really not necessary at this point.

Since types are also pretty much only a tooling convention, starting just with the most basic need/help, and iterate more complex cases later on, would be probably the best way to go.

Reading though all suggestions, I personally think these would be a no brainer to specify and ship as first iteration:

  • primitives mean primitives (i.e. string means typeof "string", no strings attached)
  • Classes and Built-ins mean classes and built-ins (i.eString means any instanceof String)
  • enum could be a new primitive (as in typeof "enum", since static and immutable) but also an expression (like classes), for enums defined as properties/fields of literals and classes
  • I actually like the auto name more than any, but without signature overloads/rides the use case would be too broad, so that maybe we should have a way to also define multiple types (i.e. const notFullyAuto: String|Object|string = value;)
  • while I know it's pretty common to have number[] as type to define an array of numbers, I also don't understand why a new syntax should have already two different ways to define typed array, i.e. const list:number[] and const list:[number], so since the latter one is more powerful/flexible, to define also multiple key/value pairs, maybe that's all we need

With these basics, the JS world would already have a huge change.

Things we might consider, but me might also don't care about, since these behaviors are part of the specs:

  • object would accept null, but since there is no typeof "null", the way to ensure null won't be there is to use Object instead. Are we OK with that?
  • number would accept NaN and -/Infinity, but IMO that's the case also without types, if a number is expected. Are we OK with that?
  • to avoid confusion with binary | operations, maybe multiple types could be wrapped in brackets, so that const index:{number|string} might look better?

That's it for my idea on how this could start moving forward.

Best

# Sultan (5 years ago)

Counter proposal: A uniform signature for types, denoted by:

const name: primitive-type<arguments...>?;

Where primitive types are denoted as:

const name: symbol; const name: string; const name: number; const name: object; const name: boolean; const name: function;

And types can later be extended to afford additional meta data as needed:

const name: string<10>; // string of length 10

const name: number<float>; // floating point number, as opposed to BigInt

const name: object<[]>; // array object

const name: object<Node>; // Node object

Union types can get added later, and denoted as:

const name: union<string, number>;

Functions can later be afforded return and argument types as denoted by:

function<void> fn (a: object<[], number>, b: string<10>?) {

return }

const fn: function<void> = (a: object<[], number>, b: string<10>?) => {

return }

# Bergi (5 years ago)

Hello, to play the devils advocate: why does JavaScript need static typing?

Your proposal doesn't really answer that. Sure, it mentions tooling and IDEs that can provide you with type hints and complain on mistakes, but things like Flow and Typescript do this today already. What's your goal, to have JS engines run Typescript(-like) code natively without transpiling? For backwards-compatibility you'd have to do that anyway, especially if new type system features are introduced incrementally.

What's the point of building this feature into engines? It just provides additional complexity. Not to mention the difficulty of finding a suitable type system that is both sophisticated enough to describe all useful code (not taking away too much flexibility) and simple enough to understand without a CS degree. And which interfaces well with un-typed completely dynamic code.

What does "static typing" even mean to you in a dynamic scripting language? JavaScript is not compiled by the developer, it is run by the user. Where (when) do you expect types to be checked? Should the engine throw early errors (during parsing)? During parsing of which parts of the code, even when "normal" (untyped) code is calling into typed code? Or do you expect dynamic runtime errors, like when assigning an invalid value to a "typed variable" or calling a "typed function" with wrong arguments? Are type definitions completely constant or could they be mutated/extended/etc dynamically (and what happens when you introduce new types with eval or by loading another script)?

A proposal would need to provide an objective that answers all these questions, before even considering any particular type system or syntax.

One way to go forward that I can see would be a proposal that reserves a relatively unrestricted syntax for type annotations (which are already considered during every grammar amendment anyway, for compatibility with Flow/Typescript), but not assign any semantics to them and require engines to simply ignore them. External tooling could then use these annotations according to its own rules.

kind , Bergi

# kai zhu (5 years ago)

i share a similar concern that static-typing makes little sense in high-churn-rate UX-workflow-programming.

it encourage people to bikeshed for correctness, on low-level code that frequently gets rewritten every few weeks/months -- and with often demoralizing effects.

# Ranando King (5 years ago)

One thing is definitively true. Any static type system added to ES must not be mandatory. Untyped code must be able to call typed code without forcing references into a fixed type. Likewise, typed code must be able to call untyped code without forcing references to give up type guarantees.

# Naveen Chawla (5 years ago)

Yes the real value of strict types, in my view, is at development time, not at run time.

However I would be curious to know if anybody has a usage for them at run time, and an example of such a case...

Otherwise, yes a "toolchain" that allows strict typing using JavaScript without having to "use TypeScript".

# Aliaksandr Zasim (5 years ago)

What about performance? Would strict types improve JIT compilation?

# Andrea Giammarchi (5 years ago)

I am having hard time understanding the counter argument "you need a transpolar anyway".

That's been the case since ES2015 landed with breaking syntax that has been required mandatory transpilation to keep it backward compatible, with things also not really transpilble such as classes with built-in extends ability.

Why suddenly the "need to transpile" is considered a point against any new JS feature? Are we already done with JS, if that's the case?

TypeScript exists and it has its own problems, 'cause its slightly diversions from what's defined via TC39 causes just confusion (i.e. private fields, to name one, built-in extends still broken if you target ES5, while Babel 7 fixed that, and template literals behave differently too - Babel 7 is the only one producing a standard behavior)

On top of that, many things recently landed in JS has been inspired by CoffeeScript ... where was the "just use CoffeeScript" argument at that time? Transpilers were already a thing then too.

Moreover ...

the real value of strict types, in my view, is at development time, not

at run time.

This is not correct. Check what AssemblyScript managed to do via types, targeting WASM instead of non-typed JS

If TypeScript, with its quirks, will be the language that help developers and win JS in the WASM field, we can start considering JS a second class citizen of the Web (and soon of the backend too, see deno).

Is this where we are with JS?

I would be curious to know if anybody has a usage for them at run time

Developers might not have such usage, but V8 / Chackra / JSC / SpiderMonkey might spin up optimizations ahead of time, enabling right away hot code.

a "toolchain" that allows strict typing using JavaScript without having

to "use TypeScript".

even if it'll end up being identical or redundant, but I doubt it, for many companies/teams the least third parts dependencies you have the better is for code reliability.

I personally don't trust TS because it breaks when it targets ES5 and I cannot control what other people target, but I would trust the standard path and tools aiming at all cost to trample it right, whenever transpiring is needed.

With Edge moving to use Chrome, and Firefox and WebKit always catching up, these days introducing anything new might need transpilers just for a couple of years, instead of decades.

Best

# Andrea Giammarchi (5 years ago)

the day I'll disable autocorrect everywhere will be always too late ...

transpolar => transpilers

trample => transpile

# Bergi (5 years ago)

I am having hard time understanding the counter argument "you need a transpiler anyway".

Sorry, I agree it's a bad argument, I should have just omitted it. It was meant to support "If you are only looking for development-time benefits, you have to install a static toolchain anyway - which might as well transpile away the annotations".

the real value of strict types, in my view, is at development time, not at run time.

This is not correct. Check what AssemblyScript managed to do via types, targeting WASM instead of non-typed JS

I would be curious to know if anybody has a usage for them at run time

Developers might not have such usage, but V8 / Chakra / JSC / SpiderMonkey might spin up optimizations ahead of time, enabling right away hot code.

...or at least allow throwing exceptions instead of having to de-optimise a JITted code, which allows simpler & better optimisation algorithms.

These are the kinds of arguments I want to hear, reasons for sending type annotations to the client/runtime. And such a goal puts a very different focus on what the type system should look like: WASM interoperability and optimiser efficiency instead of developer productivity.

kind , Bergi

# Andrea Giammarchi (5 years ago)

WASM interoperability and optimiser efficiency instead of developer

productivity.

I've personally always seen types useful only for typed languages interoperability and/or optimization/performance hints to engines/runtimes, but since many developers apparently experience some productivity boost though typed languages oriented tools, why not having all the three checked?

  • WASM interoperability (a TC39 effort)
  • more efficient runtime (a runtime/engine effort)
  • boosted productivity (a third parts tools effort)

That doesn't look too bad to me, as possible JS' future.

# Andrea Giammarchi (5 years ago)
  • trough (geeeeeeeez)
# ViliusCreator (5 years ago)

Hello, to play the devils advocate: why does JavaScript need static typing? Your proposal doesn't really answer that. Sure, it mentions tooling and IDEs that can provide you with type hints and complain on mistakes

I actually did. It keeps unwanted type mutations and bad values away. For example, This:

let a = 10
a += '1' // ‘101’
// or
a += undefined // NaN

VS this:

let a: number = 10
a += '1' // Error, cannot convert type string to type number.
// or
a += undefined // Error, a doesn’t have nullable mark.

This can help developer itself, in runtime, not only at development time. “But IDE wouldn’t allow that.” But what if property in required json(node js), is undefined? Some IDEs don’t have JSON intellisense, so this is where it can get annoying.

but things like Flow and Typescript do this today already.

Yes, but they are compile-time only. Meaning, that in runtime, type mutation and unwanted values can happen.

What's your goal, to have JS engines run Typescript(-like) code natively without transpiling?

TypeScript code is completely compile-time only. Classes(And other ES8+ code), imports, exports and probably namespaces are the only things which are at runtime also.

What's the point of building this feature into engines? It just provides additional complexity.

I said reasons above. Also as I said, they are optional. Meaning, new comers can still learn old js code without static types. Besides, doesn’t async, await, classes and other new stuff add complexity to new people to JS?

Where (when) do you expect types to be checked? Should the engine throw early errors (during parsing)?

Languages normally check types during compile-time. I expect JS to throw errors in runtime, meaning that if you make code which would throw type error and it’s untouched, then it doesn’t throw an error.

What does "static typing" even mean to you in a dynamic scripting language?

Type checking(Not like strongly-typed type checking, but no type mutation).

and what happens when you introduce new types with eval or by loading another script?

Since as I said, they are runtime only type checking. Meaning, it would check type after eval code is executed.

However I would be curious to know if anybody has a usage for them at run time

They have. eval can make type mutation(and if it checks the string, you can still overcome them(inputs or array joining)). Let's say we are importing TypeScript module through compiled TypeScript code(or other way around)(assuming we have thing which let's us import TypeScript files), then all of the enums, interfaces, etc. are completly gone, like they never existed. That's because they are compile-time only.

Also, if transpiling and compiling is better, why not leave JS dead? I mean, compilers can do job instead of JS. It’s just basically useless, compilers can do awesome stuff, so “no need for new features in JS”(and then if we did, wasm would take over in web development, or browsers would overcome ES and use something else instead).

# guest271314 (5 years ago)
let a = 10
a += '1' // ‘101’
// or
a += undefined // NaN

What if

"101"

is the expected result?

Would

"use static typing"

similar to

Strict mode for scripts

developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode#Strict_mode_for_scripts To invoke strict mode for an entire script, put the exact statement "use strict"; (or 'use strict';) before any other statements.

suffice?

# Randy Buchholz (5 years ago)

I recently started doing a lot of ES, coming from C# and really missed "typings" at first. But once I learned to think more in es, they became less necessary - even cumbersome in some ways. The question for me on this really comes down to what is a "type" and what value does it bring. As I see it, a type is a structural contract, in the same way an interface is a behavioral contract. The value of contracts is that they minimize the need to trust. I.e., if I pass a known-type to a function, I can know that it will have a specific structure (e.g., known properties and methods in a class). Without types, I must trust or check the structure. But, types aren't really self-aware. It is the environment that enforces types. Once you have types, you must have what I call a "Type Authority". Built-in types are always known by the authority, and when you declare a type, you are adding to what the authority knows. The authority can look at the code and do the "checking" of what is passed based on what it knows. Having types lets me not have to trust in what I am receiving - it can be verified for me.

In a compiled language, types provide "hidden" value. The compiler can look at the entire code based and make optimization decisions around types (e.g., in-lining). In a dynamic, interpreted language, (for the most part) this doesn't happen. Types must be processed at each point of use. So, the value of types stays mostly limited to knowing the structure. Which is though, extremely useful. The problem with static types, is that they exist at the wrong place in time. A static type is a design-time constraint. Yet the environment doesn't really know about the type until each run-time use. This puts unnecessary limits on the language - adding a property at run-time (while scary at first) is one of my favorite features of the language. Static typing adds other layers of complexity - like namespaces. Locking down a type at design-time essentially "hijacks" a name. A static type "Person" must be consistent across the entire application environment. In uses like Web, where it is common to pull code from many remote sources and libraries, how does "Person" remain "static" across these?

I would propose an alternative to static typing - the Type Authority. The Type Authority is a architecture component that (among other things) provides "scoped/run-time statics". Essentially, the Type Authority is an application-wide dynamic repository of types, in the run-time environment. This opt-in feature would allow dynamically creating types, and then making them "fixed" them with application scope. Once registered, the type is basically static. Using a hierarchal approach and "dotted" naming notation, (e.g., library.component.typename) types can be localized or extended. For example, a library can be imported, and types given a "namespace prefix". The qualified name would effectively be a static type within the application context. Properties could be dynamically added, and the new type registered as a "child type" (e.g., Person => Person.Domain). This would then allow casting - (Person)DomainPersonInstance. A simple Type Authority would support basic "is a"/"typeof" capabilities. A more advanced system could provide factory methods.

This approach provides a way to enforce the structural contract nature of types, while retaining the dynamic nature of the language.

# Ranando King (5 years ago)

Doesn't V8 already use such a concept to manage optimization? When a reference's structure mutates, V8 generates a new type by extending the previous one with the changes, then kills any affected optimizations around the mutated object, forcing re-optimization. Static types would essentially provide a guarantee that such re-optimizations would be completely unnecessary for the lifetime of the object since it would be impossible to mutate the object's structure. It would also allow for early optimization since the structure would already be known. These are the benefits of static typing. It's not just a matter of developer trust but also engine efficiency.

# Dan Peddle (5 years ago)

It's really a shame few mention jsdoc anymore. It provides mechanisms to achieve all of these developer experience quality of life improvements without needing transpiling, and on top of standard js of various flavours, progressively.

# Andrea Giammarchi (5 years ago)

jsdoc doesn't exist in production so it cannot provide any info to the runtime, making WASM interoperability and hot code optimizations impossible.

Let's please keep the discussion focused on the achievements current JS cannot possibly have, thanks.

# Andrea Giammarchi (5 years ago)

Actually, on that very same note, since WASM <-> JS might be the only

reason, or likely the best one, to have types in JS, let's consider from scratch all WASM types as possible primitives to adopt, shall we?

i32 (alias as int?) i64 f32 (alias as float?) f64 u32 (alias uint?)

then we have functype (function) limits (dynamic arrays) memory (static arrays) and tables (objects/maps) to deal with, plus global and external.

If we find a syntax to represent these types, targeting, or consuming in an optimized way, WASM, might be a reality, with better results than asm.js, since that's very hard to write / remember for humans, IMO.

I also would like to know the opinion of someone close to V8 or other engines.

# Michael Theriot (5 years ago)

On Monday, March 25, 2019, ViliusCreator <viliuskubilius416 at gmail.com>

wrote:


let a = 10

a += ‘1// ‘101’

// or

a += undefined // NaN

VS this:


let a: number = 10

a += ‘1// Error, cannot convert type string to type number.

// or

a += undefined // Error, number doesn’t have nullable mark.

Thought experiment:


let a = 10;
let b: number = 10;
a === b; // true

Would an error at runtime or compiletime occur here?


a += '1'; // ok
b += '1'; // error

If it is a runtime error, is it optimal for the engine to keep track of typed variables vs regular for the same value?

If not and it is a compiletime error, what happens here?


var x = something();

a += x;
b += x; // error?

# Claude Pache (5 years ago)

Le 27 mars 2019 à 18:26, Michael Theriot <michael.lee.theriot at gmail.com> a écrit :

Would an error at runtime or compiletime occur here?

The check cannot be reliably done at compile time in general; it must be a runtime check. (Tools may provide partial static analysis, but that’s an extra.)

The simplest reason is that statically typed code must run together with non-statically typed code.

And even ignoring legacy code, it is not desirable to have static types everywhere; for instance, Array.prototype.sort() must continue to work with both arrays of strings and arrays of numbers, and even with arrays of mixed types.

And even if everything everywhere was statically typed, you still cannot statically analyse situations like: a = object[Math.random() < 0.5 ? "method_returning_number" : "method_returning_string"]().

If it is a runtime error, is it optimal for the engine to keep track of typed variables vs regular for the same value?

Today’s JS engines typically do already clever speculative optimisations based

# guest271314 (5 years ago)

a = object[Math.random() < 0.5 ? "method_returning_number" : "method_returning_string"]()

Interesting case. See also

How do I check if a JavaScript function returns a Promise? stackoverflow.com/q/43416214

Say I have two functions:

function f1() { return new Promise<any>((resolve, reject) => { resolve(true); }); } function f2() { }

How do I know if f1 will return Promise and f2 will not?

Can a regular expression be crafted which determines the return type of a function? stackoverflow.com/q/43417236

Has it been mathematically proven that antivirus can't detect all viruses? security.stackexchange.com/q/201992

# Ranando King (5 years ago)

Would an error at runtime or compiletime occur here?

There's no "compile time" per se in ES, but setting b += '1' when b is strictly typed shouldn't throw an error at all. The type of the '1' would be coerced to a number first, then added to b.

If instead it was something like

let a: string = "1";
let b: number = 2;
b += a; //TypeError

This would cause an error because it would be invalid to coerce a into a number.

If it is a runtime error, is it optimal for the engine to keep track of

typed variables vs regular for the same value?

Engines like V8 already keep track of the type of variables. Static typing would simply add a flag to these types that prevents type coercion if set.

# Waldemar Horwat (5 years ago)

On 3/23/19 1:34 PM, IdkGoodName Vilius wrote:

This is a proposal for static typing. Here is the github repository link: CreatorVilius/Proposal-Static-Typing I think it would be great thing in JS.

We intentionally reserved syntax so that something like that would be possible in the future.

I've also spent a lot of time working on past proposals to do such things. A few interesting issues would invariably arise that make both static and runtime typing unsound:

  • If you allow user-defined types, objects can spontaneously change their type by mutating their prototype. Thus, you can declare a variable x to have type Foo and check that you're assigning an instance of Foo to it, but the value x can become a Bar (different from a Foo) spontaneously without any operations on x.

  • Something similar happens with trying to type arrays. You wrote:

let c: auto = ['a', 'b'] // c is now string[]

but that begs the question of what is the type of just ['a', 'b'].

  • Is it string[]? No, it can't be that because you can replace its second element with a number.
  • Is it any[]? Well, in that case c should have type any[], not string[]
  • Is it object? In that case c should have type Object. and so on.

If you follow this to its logical conclusion and think about what the types of various methods that work on arrays should be, you end up with an enormous and confusing variety of array and object types, which is something we explored years ago. In some cases you'd want structural types, in some cases you'd want 'like' types (an array of anything which just happens to hold numbers at the moment), and so on.

 Waldemar
# Ranando King (5 years ago)
  • If you allow user-defined types, objects can spontaneously change their

type by mutating their prototype. Thus, you can declare a variable x to have type Foo and check that you're assigning an instance of Foo to it, but the value x can become a Bar (different from a Foo) spontaneously without any operations on x.

At least for static typing, the engine will need to freeze a copy of the class definition at the time when the static type is referenced. That frozen type will be associated with the variable in a fixed way, making all attempts to change the type of the variable fail. Also, that would need to divorce the frozen type from the dynamic version so the dynamic version can still be mutated. That concept should work, but it might prove to be ridiculously complicated since it risks a proliferation of objects all of type Foo but with different type definitions. One way to get around that is to flag a type as static the first time it is used in a statically typed variable definition. This would cause an error to be thrown should any part of the class be altered. Not sure how workable that is.

but that begs the question of what is the type of just ['a', 'b'].

It should be any[]. Typing should be as non-aggressive as possible. Auto typing should only consider the top level data to determine the type, and in this case, that's an Array. To make c restricted to string elements, the type would need to be specified as string[].

If you follow this to its logical conclusion and think about what the

types of various methods that work on arrays should be, you end up with an enormous and confusing variety of array and object types, which is something we explored years ago.

Maybe, but that's always the case with any type system that allows for user-defined types. The main problem here is the memory requirements for storing all of those types. If I remember the description of V8 internals, it seems to have already managed this issue. At least in V8, the challenge would be in permanently associating a specific evolution of an internal type to a variable.

# Andrea Giammarchi (5 years ago)

If something is missing, let's move forward finding out solutions, 'cause if we base any assumption only to the current highly dynamic nature of JS we won't go too far.

As example, I think the mutable prototype issue can be solved through static classes where no changes would be possible and all instances would be immune to setPrototypeOf

static class MyType {}

Reflect.setPrototypeOf(MyType, Array); // nope
Reflect.setPrototypeOf(new MyType, []); // nope

we'll also need a Reflect.isTyped(ref) in case we'd like to throw errors on prototype set attempts.

# Ranando King (5 years ago)

if we base any assumption only to the current highly dynamic nature of

JS we won't go too far.

Problem is that if we infringe on the "current highly dynamic nature of JS", we'll end up breaking valuable use cases. Any new feature added should always be 100% compatible with the non-competing portions of the existing language.

I think the mutable prototype issue can be solved through static classes

where no changes would be possible and all instances would be immune to setPrototypeOf

That solves half of the problem. What of the other half (Type v = "somevalue"; where Type is not a static class)? With your approach, that would need to be restricted to solve the other half. Otherwise, you'd still be facing the issues Waldemar spoke about.

# Andrea Giammarchi (5 years ago)

we could add a Typed primitive every typed value inherits from, similar way every object implicitly inherits from Object these days.

That, by contract, would disallow any prototype related operation to either classes or instances, and it will simplify the Reflect.isTyped(thing) algo.

class MyType extends Typed {} const num:i32 = 123;

the MyType class, and every instance of it, cannot have mutated prototype, and so cannot the num.

Typed values will be all shortcuts that behave like a Typed instance.

That should solves all cases, right?

# Ranando King (5 years ago)

That should solves all cases, right?

Only if a non :any type must extend Typed(). Put another way:

class MyType extends Typed {} class OtherType {}

let a: any = new Object; //Valid let b: OtherType; //Error: Invalid type specification let c: MyType = new Object; //Error: Invalid cast assignment let d: MyType = new MyType; //Valid

# guest271314 (5 years ago)

Two possible solutions to the requirement of not being able to change a "type" both include utilizing const.

  1. Using Object.freeze()

const x = Object.freeze([1,2,3])

  1. Using Promise.resolve()

const x = Promise.resolve([1,2,3]); x.then(data => /* data will always be [1,2,3] */)

neither of which can be deleted or changed within the current scope; i.e, Is it possible to delete a variable declared using const? stackoverflow.com/questions/42424019/is-it-possible-to-delete-a-variable-declared-using-const

# guest271314 (5 years ago)

Similar concepts: not being able to re-declare a variable in any or a specific scope, or a "superconst" or "Scope Controller"

# Jordan Harband (5 years ago)

const means it can't be reassigned, but a non-frozen value can still have its properties changed or its [[Prototype]] changed (including Promise, which could have its .then method changed), which would change the type.

# guest271314 (5 years ago)

Yes, the [[PromiseValue]] could theoretically be changed, given adequate effort. Is it impossible to get the [[PromiseValue]] from a Promise object without using the Promise object's then method? [duplicate] stackoverflow.com/q/41201360. The example of using Object.freeze() could also be extended to the value passed to Promise.resolve().

Using const with Object.freeze() and possibly WeakMap could be utilized for the use cases described. rustwasm rustwasm/wasm-bindgen is an active repository for "Facilitating high-level interactions between wasm modules and JavaScript" and have several issues addressing types rustwasm/wasm-bindgen/issues?utf8=✓&q=is%3Aissue+Types+ wasm and JavaScript, which might be helpful for specific and general issues encountered relevant to types (see also cdn.rawgit.com/WebAssembly/wabt/aae5a4b7/demo/wat2wasm).

Determining if a value is an (JavaScript plain) Object (which leads to the question "Why is null an "object" in JavaScript"?) is a task in itself How to filter Object using Array.prototype.filter? stackoverflow.com/q/36232576; Why is there not a built-in method in JavaScript to check if an object is a plain object? stackoverflow.com/q/40456491, and even if this proposal were implemented would/could it halt/stop any, all or only some usage of the assignment operator (even for "built-ins" stackoverflow.com/questions/40456491#comment68436319_40457385) Object = 1; // should a TypeError be thrown here? Object.entries([]) // Uncaught TypeError: Object.entries is not a function

# Ranando King (5 years ago)

Similar but not the same. Within any given scope, a Type declared within that scope would need to be "set-in-stone" to be of any value. Furthermore, for a variable to honor that type, it must be able to carry around an unmodified reference to the tyoe as it existed at the time the variable was declared. If either one of these two conditions is not met, then the type system cannot claim to be static. It would be more of an "advisory" dynamic type system, where the specified type gives the engine a hint on what kind of data will be stored in a given variable.