I'm working on an incompatible language, Violent ES since 2017. It has a full parser already, but since it's typed, it needs a verifier/symbol solver. It aims to have some features of ES2015 (destructuring patterns, yield, await, import.meta, arrow functions (uses ->, not =>), optional chaining, global) mixed with the syntax of the inexistent ECMAScript 4th edition (package{}, implicit yield, include, getters, setters, type T = ...;), some fundamental changes (String aims to have the same composition as Python's str data type (code points, not UTF-16 code units)) and type expressions (* (dynamic), void, undefined, null, union, records, tuples, functions and more), generics (where clauses as well) and enums (variants use same convention as ES (like E.FOO_BAR, or 'fooBar' when inferred), and flags enum).

  • Type system aims not to be erased at runtime. Further, it also aims to be runtime reflexive, through the Reflect namespace.
  • Value classes are supported. They're represented the same way as records. [Value] class P { const x:Number; }
  • Enums similiar to .NET, but more powerful.
  • Flags enums are supported.
  • Simple decorators using brackets. Different from ES, parameters cannot have decorators, only ordinary annotatable definitions (namespace, class, enum... not sure about interface and type).
  • global is a reference to the top-level package{}
  • include './further.es'; statement includes further statements from the given source. Useful for splitting large code. Can appear anywhere, really (but packages can only be defined from ordinary scripts).
  • Record types are values, not references: type R = {x:Number, y:undefined|Number};
    • thus var r:R = {x:10}; r == {x: 10};
  • Tuple types are values, not references: type T = [Number, Number];
    • thus var t:T = [0, 0]; t == [0, 0];
  • Generics use g.<T> syntax, not g<T> (for desambiguation, just like planned in ECMAScript 4th)
  • package foo.bar { namespace Temporal {...} }
  • Different ways to alias packages:
    • import Fb = foo.bar.*;
    • namespace Fb = 'foo.bar';
  • The operations o[k], delete o[k] and k in o work in a separate indexing mechanism through proxy declarations, thus built-in types like Map will use these operators instead of m.get(k), m.set(k, v), m.delete(k); (as there won't be name conflict).
    • Reflect namespace may be used for computing properties at runtime.
  • Thrown errors are tracked at compile-time. Use throws clause when needed. When you take a function as the dynamic Function type, all errors are uncatchable.
  • To throw uncatchable errors, use uncatchableError(message).
  • embed expression (static resource embedding): embed './data.bin', embed './data.txt'

There are lots of details about this language covered in its main GitHub repository. To those who are familiar to ActionScript, the only downside is that declarations such as classes are different from ES2015. For example, in ES2015 you've:

class C {
  constructor() {
    // constructor

In Violent ES, ECMAScript 4th or ActionScript, you've:

class C {
  function C() {
    // constructor

And there are no modules but packages. Other than that, Violent ES has only more advantages compared to ES. The major reason why I'm building this language though is its different type system compared to TypeScript (TS performs erasure). The best features I guess are the natural records and tuples.

Generics and type expressions aren't complex as in TS, but it has more type expressions than Haxe (which is also based in ES4).

If you like it, please leave your feedback!

About decorators I forgot to add that function, var and const can also have them. I've not documented how decorators will work yet, but basically any annotatable definition can have them.