Optional Typing

Is there any hope of optional typing landing in ecmascript in future? Checking arguments at top of scope in functions, methods and constructors is getting really boring. It could even open the door to allow ecmascript to be a reasonable option for writing wasm.

1 Like

Have you experimented with TypeScript at all?

There's also AssemblyScript.

@aclaymore @senocular I use both TypeScript and AssemblyScript, and I'm avid in the AssemblyScript community, working on projects like,

and others.

It would be really nice to have type syntax officially in EcmasScript. This would also, as @ReinsBrain mentioned, open the door to compiling to WebAssembly (or even native) in a standard way, and would allow multiple implementations (even the browser engine) to exist and be interoperable.

If people could opt into type syntax and get type checking in the JS engine without any tooling, that'd be a huge win for the large amount of entry developers looking to easily start writing apps with minimal barrier to entry.

TypeScript and AssemblyScript both require a fair amount of build system knowledge in comparison.

1 Like

The following discussion moved here:

@ljharb the last thing you mentioned about the possibility of preventing (with string pragmas) a backwards compatibility nightmare if we were to enable optional types that the interpreter ignores and then making then errors later, was

@trusktr at present i don't believe it can ever possibly be prevented.

Would it better if we started with a tiny set of type features that introduce errors at the same time, so we con move forward towards the eventual best path? (avoiding a big all-at-once thing that might include mistakes we may regret?)

What I'm imagining is then something like what @WebReflection mentioned:

// no types used here
let a = 123
let b = a // ok
let c = b // ok
a = "string" // ok
b = a // ok
c = b // ok

then we can start to introduce types:

// type annotations added to the file

// do we want more-specific number types? Maybe `number` is the most generic and we can add more later?
let a: number = 123

let b = a // ok, b inferred as `number`
let c = b // ok, c inferred as `number`

a = "string" // causes an error (at runtime? or at parse time?), 'string' not assignable to 'number'

// These would be ok according to the inferred types, but this code is irrelevant due to the previous error.
b = a // ok
c = b // ok

The following is a live example of the type error using Hegel.js:

Hegel Playground example

Hegel is a highly-inferring type system that is capable of making meaningful types out of plain JavaScript without type annotations, but type annotations can be used to specify intent as needed in order to override inference. TypeScript on the other hand likes to make everything type any, which is less beneficial.

A new version of Hegel is in the works but not released yet:

Here is another example showing Hegel's type inference on the same example, but without a type annotation:

Hegel Playground example

Here's a more advanced example including a function, still with no type annotations:

Hegel Playground example

I'm not sure how we could enable such a type inferring system in JavaScript without it being a breaking change (@ljharb any ideas?). Maybe the only way is to opt in with type annotations?

Being able to have the sort of type inference as in Hegel without requiring type annotations is really convenient and useful.

I don't understand how string pragmas can help in any way with syntax additions.

My understanding of string pragmas is that they change the runtime behavior in a backwards compatible way, so that implementations that don't recognize the pragma simply ignores it. Thus the changes enabled have to be strictly runtime and less permissive that without the pragma.

Type annotations are usually in the form of new syntax (except for JSDoc style), which wouldn't be parse time compatible. The only thing I can imagine is a one time breaking change to carve out a place where typing syntax can live an be ignored at runtime (aka make TS/Flow valid JS syntax), then in the future add string pragmas to opt into some kind of runtime check based on a specific flavor of the typings.

However my understanding is that even a syntax carve out for typings previously failed or got stuck. For example GitHub - samuelgoto/proposal-optional-types: A proposal for an optional type system for JS.

Or, we could go with what we already have: lintable comments that provide non-runtime annotations and can never cause runtime behavior in any edition of the spec. JSDoc is one flavor (or set of flavors, since there’s multiple kinds of jsdoc), but you could certainly invent your own.

Having done, JSDoc style typing as well as Flow and TypeScript, I admit that there is a significant overhead with stuffing type annotations into structured comments. JSDoc is fairly cumbersome compared to TS/Flow. Furthermore, most syntax used by TS/Flow is virtually unavailable to JavaScript at this point (as-is JSX unfortunately), so an argument could be made that introducing type carve outs is codifying reality. While I'd personally love to see inert typing syntax in JavaScript, I sure am not willing to pick up that battle.

2 Likes

runtime type checks would be so awesome though. So the syntax would have to have runtime behavior up front to make that possible, and to avoid having one inert syntax, and one runtime syntax (if the first syntax takes up all the space, just imagine what the second one would look like).

If you haven't seen them, there are libraries that have looked at taking the 'inert' syntax and outputting the necessary runtime checks:

e.g.

function f(v: string) { ... }

compiles to something like:

function f(v) {
    assertString(v);
    ...
}

Look what people voted for in State of JS:

2 Likes

Microsoft is putting inertia behind this proposal:

3 Likes

They're doing the same thing I suggested "type hinting", a.k.a types as comments;
Which nobody here's interested in unfortunately.