Proposal: Optional Static Typing (Part 3)

Brandon Andrews warcraftthreeft at sbcglobal.net
Tue Jan 16 00:46:06 UTC 2018


>> Part of this has had me considering if freezing classes (and all recursively referenced types) used in the type system is viable. 


```js
function foo(bar: Array.<Set>)
{
// whatever
}
[Array, Set] = [Set, Array];
foo(new Array([Set()]));
```

> You can't freeze all builtins for obvious reasons. 


I'm out of ideas. Do you or anyone here see a way to get around such an issue?

> You totally omitted point that your type system can't use or describe this function: 


```js
function issue(Ctor)
{
    	assert(Reflect.isConstructor(Ctor)); // Type system don't provide way to disguintish object with [[Construct]] and [[Call]] methods.
    	assert(Foo.isPrototypeOf(Ctor)); // Type system don't provide way to ensure prototypal inheritance
     
    	const retClass = class extends Ctor // Type system don't provide way to describe types being returned from function
    	{ 
    	};
    	Object.assign(retClass.prototype, mixin); // Object.assign can be overridden to do anything, so actual code execution is required to prove it's valid
    	return retClass;
}
```

Just to be clear. Is Ctor a type? Like "class Ctor extends Foo {}" or an instance? If it's a Type it might be better handled with generics later like:

```js
function issue<Ctor extends Foo>(mixin)
{
    	const retClass = class extends Ctor
    	{ 
    	};
    	Object.assign(retClass.prototype, mixin);
    	return retClass; 
}
```

I hope I understood the requirements. Is it necessary to allow the type system to handle passing types as arguments? Do other languages allow this?

```js
assert(Reflect.isConstructor(Ctor)); // Type system don't provide way to disguintish object with [[Construct]] and [[Call]] methods.
```

So you'd expect a language feature like an interface that mandates a constructor or something more general like "this object is a class"?

```js
assert(Foo.isPrototypeOf(Ctor)); // Type system don't provide way to ensure prototypal inheritance
```

So I should explicitly state that derived classes can be passed to parameters typed with their super like most languages allow like:

```js
class A {}
class B extends A {}
function f(a:A) {}
f(new B()); // Valid
```

In your example:

```js
function issue(Ctor:Foo):Foo
{
}
class A {}
// issue(new A()); // TypeError, A must be type Foo or extended from Foo
```

Is that sufficient?

```js
const retClass = class extends Ctor // Type system don't provide way to describe types being returned from function
{ 
};
```

Would this be asking for interfaces and structural matching like in TypeScript? I left it out originally to simplify the proposal with the expectation it would be added in later. Do you see this more as a mandatory feature? "any" can be used in the meantime unless I'm mistaken. (I should probably add a section in the proposal covering this).


More information about the es-discuss mailing list