I try to implement pipe-operator overriding |
extension Pipe on Object {
operator |(Function(Object) f) => f(this);
}
typedef Id = A Function<A>(A);
Id id = <A>(A a) => a;
var t1 = id("test"); // String t1
var t2 = "test" | id; // dynamic t2
with the generic Id function above, on id("test") is detected as String, but "test" | id is dynamic which is very problematic.
How can I fix this?
EDIT
Thankfully, @jamesdlin has answered and suggested:
extension Pipe on Object {
Object operator |(Object Function(Object) f) => f(this);
}
the result has improved as
var t2 = "test" | id; // Object t2
I also tried with generic as follows:
extension Pipe<A, B> on A {
B operator |(B Function(A) f) => f(this);
}
I expected it would go better because I thought the generic A B is more specific and better than Object ; however, the result goes as bad as before:
var t2 = "test" | id; // dynamic t2
Why the generic does not work? Is there any way to make the dart compiler infer it as string ?
CodePudding user response:
Your operator | extension does not have a declared return type. Its return type therefore is implicitly dynamic. Also note its callback argument does not specify a return type either, so that also will be assumed to be dynamic.
Declare return types:
extension Pipe on Object {
Object operator |(Object Function(Object) f) => f(this);
}
(Answering your original question about a NoSuchMethodError: when you did
var x = "test" | id;
x | print;
x has type dynamic, but extension methods are static; they are compile-time syntactic sugar and will never work on dynamic types. Consequently, x | print attempts to call operator | on the object that x refers to, but that object doesn't actually have an operator |.)
