HaxeFoundation / HaxeFoundation/haxe
add RuntimeType<T> constraint
- Dominant language
- Haxe
- Stars
- 6.9k
- Forks
- 715
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 11
Description
What I often want is to allow using abstracts over specific type as type parameters without requiring them to be convertible to that type from the outside.
For example, imagine we wanted to provide an alternative to `haxe.DynamicAccess` that would allow abstracts over `String` for keys. Obviously we need to constrain the key type parameter to `String`, since it's required at run-time:
```haxe
abstract JSObject(Dynamic) {
public function new() this = {};
public function get(key:K) return Reflect.field(this, key);
public function keys():Array return Reflect.fields(this);
}
abstract ItemId(String) {}
new JSObject();
```
Unfortunately this will not compile according to current rules, because:
1) The `ItemId` abstract is not actually compatible with `String` since there's no `to String`.
2) `Relfect.fields` returns `Array` which is incompatible with `Array` due to invariance.
Currently there's no way to represent this in type system without losing safety in some way (adding `cast`s and/or `to String` to the abstract).
To solve this I propose adding a new compiler-handled constraint to `haxe.Constraints`, such as this:
```haxe
abstract RuntimeType(T) from T to T {}
```
Then we could use it as a constraint, e.g. `abstract JSObject,V>`.
Compiler would allow unifying `RuntimeType` with any types that are represented as `T` at run-time even if they don't define direct casts to `T`. Also it would allow unifying type parameters constrained with
`RuntimeType` with them.
Contributor guide
Assessment
This issue has not been assessed yet.