sirisian / ecmascript-types

ECMAScript Optional Static Typing Proposal http://sirisian.github.io/ecmascript-types/
453 stars 4 forks source link

Syntax for assigning multiple overloaded functions to a variable/argument #47

Open sirisian opened 5 years ago

sirisian commented 5 years ago

There's ad-hoc syntax in the spec for this in one place: https://github.com/sirisian/ecmascript-types#generator-overloading

There needs to a consistent syntax though for this that works everywhere one would assign multiple overloaded functions. Essentially this boils down to:

var a = () => {};

Now what if we want to assign multiple functions to a?

var a =
[
  () => {},
  (a:bool) => {}
];

That syntax doesn't work for the obvious reason that it's an array and a is dynamically typed. We could apply constraints that a must be typed with a function interface, but this means using typed assignment only treats it like an array.

var a :=
[
  () => {},
  (a:bool) => {}
]; // a is an array
// a(); // TypeError: a is not a function
interface IExample
{
    ():void;
    (:bool):void;
}
var a:IExample =
[
  () => {},
  (a:bool) => {}
]; // a implements IExample

There's a whole idea also that an array of functions can be assigned to a variable/argument implementing an interface which seem intuitive. This is all kind of an edge case I believe and won't be used much by developers.

Is there a better syntax? Does allowing typed assignment to differentiate between arrays and function overloads have merit/usefulness?

sirisian commented 5 years ago

In the extending function interfaces example here: https://github.com/sirisian/ecmascript-types#extending-interfaces the whole example would look like:

interface A
{
    (string):void;
}
interface B extends A
{
    (string, string):void;
}
function F(a:B)
{
    a('a');
    a('a', 'b');
}
F([
    a => a,
    (a, b) => a + b 
]);

I could probably create a more realistic example like if you're serializing with a visitor pattern function and you pass in an overloaded example that handles individual types returning some converted value. Might leave that for a gist example.