-
Notifications
You must be signed in to change notification settings - Fork 219
Description
Context
As I've commented on dart-lang/sdk#56028.
Consider:
mixin M { void m(); } class M1 with M { const M1(); @override void m() {} } class A<T> { const A(this.o); final T o; } class B<T extends M> extends A<T> with M { const B(super.o); @override void m() => o.m(); } void foo<T>(T o) { late A<T> a; if (o is M) { a = B<T>(o); // 'T' doesn't conform to the bound 'M' of the type parameter 'T'. Try using a type that is or is a subclass of 'M'. } else { a = A<T>(o); } }
Today this code has only "bad" solutions (the basic ways I could think of were not able to solve this and I could not think of another solution than the following), one which was proposed later on that same issue involves calling a helper function with (fn as Function)<T>(...)
. This is doable by the programmer but it's easier to get it wrong.
From @eernstg in dart-lang/sdk#56028:
void foo<T>(T o) { B<S> fooHelper<S extends M>(S o) { // In this body the type system knows that `S extends M`, // so we can create a `B<S>`. return B<S>(o); } late A<T> a; if (o is M && <T>[] is List<M>) { // At this time we know that `T extends M`. The type system // won't recognize that, but we can force it using a dynamic // invocation of a generic function. a = (fooHelper as Function)<T>(o); } else { a = A<T>(o); } }
Request
I'd like to request/propose that type arguments could be tested for specific bounds.
That would not only return a true
or false
for the test expression, but it would also consider that in the inner context.
That would make it so that in this context:
void foo<T>(T o) {
late A<T> a;
if (T <: M) { // Trying to imitate your writings from previous issues but if I got it the wrong way around please disconsider
a = B<T>(o); // Here `T` would then be considered as a subtype of `M` and could be used as the type parameter on `B`
} else {
a = A<T>(o);
}
}
This would be more of a "help" for the language to type-solve harder contexts.