Description
One proposal is metaobjects
And to use this feature, objects have to implement a "static interface":
abstract class Decodable<T> {
T fromJson(Map<String, Object?> json);
}
class Person static implements Decodable<Person> {
@override
factory Person.fromJson(Map<String, Object?> json);
}
This is cool! But having to implements
the interface is very inconvenient.
In particular, having to implement an interface makes it difficult to support objects that we have no control over.
Imagine the following code:
abstract class Empty<T> {
T empty();
}
T example<T static implements Empty<T>>() => T.empty();
Then even though List.empty()
or Stream.empty()
exist, we cannot do example<Stream<int>>()
.
Could this be solved by introducing a different kind of interface? One that is implicitly implemented by all objects which match its prototype?
Consider:
struct Named {
String get name;
}
We could support:
class Person {
String name = '';
}
print(Person() is Named) // true
This would enable changing our previous Empty
example to:
struct Empty<T> {
T empty();
}
example<Stream<int>>(); // OK
Going further: Should static extensions integrate with structs?
A separate proposal is about static extensions
A common use-case for this is to add new constructors on a class.
For example, adding a DateTime.fromJson
:
static extension on DateTime {
factory DateTime.fromJson(int json) => ...
}
DateTime.fromJson(0000);
It would be great if static extensions could combine with structural typing, such that we could have:
static extension on DateTime {
factory DateTime.fromJson(int json) => ...
}
struct Decodable<T> {
T fromJson(Object obj);
}
void example<T static implements Decodable<T>>() {}
example<DateTime>();