kaleidawave/ezno

Nominal classes

kaleidawave opened this issue · 1 comments

#126 adds allowing creating classes as a type which can be referenced

As of #126 they are treated as being nominal. Given

class X { a: number = 2 }

The only two cases of types where instance passes is for

const x: X = instance

is when

  • Type::Constant has a base type (there is a function in the code which does this) that is X. (this is because string, number and boolean are treated as special classes)
  • Type::Object where the information.prototype.get(object_type_id) is X

Therefore it does not perform property checks for let x: X = { a: 2 } and so will raise a type error. However it only works one way, so let x: { a: number } = new X is fine.

There is also some benefit to the variable_current_value and side effect system which means that shouldn't create to many issues. For let x: { a: number } = new X, x still has the class instance of X type as it doesn't widen.

This can simplify things. In the future:

  • The methods on X can be treated as a known function and therefore know the side effects (if they are already registered)

However TypeScript allows both ways. There may be a way in the future for a CLI flag to check properties (and also drop that for (x: Set<number>) => x.add x.add might not be the Set.prototype.add function)

This is now implemented. This hopefully allows the checker to assume methods on Array etc have known effects.

Might need revisiting, but good for now 👍