Open srawlins opened 2 years ago
- What about inheritance? If a method
D.f
overrides a methodC.f
, with a parameter annotated with@returnType
, must the corresponding parameter inD.f
also be explicitly annotated?
Given normal override rules I would say no, it's allowed to expand the type to a more general type (ie: Function
) in this case. If it wanted to call super
though then it would have to duplicate the annotation.
Would or could such an annotation affect type flow analysis?
For example, would you need to still null check the return value from an annotated function?
int square(@returnType<int Function()> Function cb) {
final value = cb()!; // Would the ! still be necessary, or could it be omitted?
return cb * cb;
}
Or would this simply produce an error at the call site of square()
?
Would or could such an annotation affect type flow analysis?
Nope.
For example, would you need to still null check the return value from an annotated function?
Yes, if it does today. (E.g. if the default return type is dynamic
, which I think it is. Then value
would be dynamic
without the !
and cb * cb
would be dynamic invocation.
Does this still make sense? Perhaps if there was no other user, and it wasn't needed so far, let's close the issue?
I think this request still makes sense. Our team keeps issues open even if we have no plans to implement it, for searching, tracking, and discussion purposes. But we can make it P4 if Angular has chugged along OK without it, and no one else has chimed in that it would be useful.
This request is specifically for the Angular team, but can be used generally. The problem is as follows: given a function with the following signature:
void foo(Function cb)
there is no way to specify that
cb
must return a non-nullable type. For whatever reason, the type ofcb
cannot be function-typed (likeint Function(bool)
), and the most narrow type that can be specified isFunction
. The return value can be null-checked at runtime, but it would be much better to catch this statically. One idea is an annotation like so:void foo(@returnType<Object> Function cb)
orvoid foo(@ReturnType(Object) Function cb)
With recent language versions of Dart, either of these could specify a function type or a type with type arguments:
void foo(@returnType<int Function(bool)> Function cb)
void foo(@returnType(int Function(bool)) Function cb)
void foo(@ReturnType<List<String>> Function cb)
void foo(@ReturnType(List<String>) Function cb)
I think I prefer the
@returnType<Object>
API.The rules for this annotation are:
Function
@returnType<X>
, any argument given for this parameter must be function-typed and the return type on the function-type must be assignable toX
.@returnType
. I think the decision about allowing this is just how difficult it is to implement.Open questions:
D.f
overrides a methodC.f
, with a parameter annotated with@returnType
, must the corresponding parameter inD.f
also be explicitly annotated?dynamic
be allowed, as the only type which can be explicitly cast to other types? Explicitly bandynamic
except for@returnType<dynamic>
?CC @leonsenft @jakemac53 who helped design this yesterday.