Comments (6)
Closing in favor of #907, which enables more advanced class hierarchies.
Alternatively, you can use @Implements
/@With
to do things by hand.
from freezed.
That is currently not supported.
But, it is not impossible to support it.
A more complex case I would like to fully support is:
abstract class Complex with _$Complex {
const factory Complex.a(int value) = ComplexA;
const factory Complex.b(double value) = ComplexB;
}
I'm thinking of a few things for these cases:
Complex example = Complex.a(42);
num value = example.value; // fine
double value = example.value // implicit-cast error, value is a num not a double
example.value
would be num
because that is the nearest common type between double
and int
Then one more difficult scenario would be:
abstract class ReallyComplex with _$ReallyComplex {
const factory ReallyComplex.a(int variable) = ReallyComplexA;
const factory ReallyComplex.b(double variable) = ReallyComplexB;
const factory ReallyComplex.c() = ReallyComplexC;
}
In which case I think I'd go with:
ReallyComplex example;
example.$variable(
(num variable) => print(variable),
orElse: () => print('nothing'),
);
The $
being necessary so that we can still do:
ReallyComplex example;
if (example is ReallyComplexA) {
print(example.value);
}
from freezed.
what would that look like for my example?
abstract class Result with _$Result {
const factory Result.Continue(Action action) = Result_Continue;
const factory Result.Retry(Action action) = Result_Retry;
const factory Result.Complete() = Result_Complete;
}
result.$variable(
(Action action) => process(action),
orElse: () => print('nothing'),
);
and if I wanted to differentiate between continue and retry I would have to vary my type (ActionContinue or ActionRetry or something like that)
abstract class Result with _$Result {
const factory Result.Continue(ActionContinue action) = Result_Continue;
const factory Result.Retry(ActionRetry action) = Result_Retry;
const factory Result.Complete() = Result_Complete;
}
result.$variable(
(ActionContinue action) => process(action),
(ActionRetry action) => wait 5.then(process(action)),
orElse: () => print('nothing'),
);
...if I have that right then I think that would work well. It would be nice to vary by the continue and Retry types though and not by the parameters. In my example an Action is always an Action but the Result is the type that determines whether an action should Continue or Retry), maybe that is impossible as everything works around the parameters and not the types? but, if the syntax is possible, maybe an as
keyword could work?
abstract class Result with _$Result {
const factory Result.Continue(Action action) = Result_Continue as ResultAction;
const factory Result.Retry(Action action) = Result_Retry as ResultAction;
const factory Result.Complete() = Result_Complete;
}
result.maybeWhen(
ResultAction: (action) => process(action,
orElse: () => 'fallback',
or
result.maybeWhen(
Result_Continue: (action) => process(action),
Result_Retry: (action) => retry(action),
orElse: () => 'fallback',
from freezed.
An alternative is to make the properties that are not shared between all constructors nullable.
Since Dart will "soon" have non-nullable types, it should be compile safe.
Freezed could still generate that$my_property
variant for more complex cases.
from freezed.
I haven't thought this through that much (!) but could you go for a ducktyping approach? In my example above all I really want to do is run code wherever I have a property called action of type Action.
abstract class Result with _$Result {
const factory Result.Continue(Action action) = Result_Continue;
const factory Result.Retry(Action action, int retryTime) = Result_Retry;
const factory Result.Complete() = Result_Complete;
}
main() {
var result = Result_Continue(Action());
result.maybeWhen(
action: () => print("action"),
action_retryTime: () => print("action in retrytime"),
retryTime: () => print("retry time")
_void: () => print("everything "),
);
}
vary by the property names rather than the types because an int
may not be descriptive enough - age & height for example could be two different parameters
from freezed.
A more complex case I would like to fully support is:
abstract class Complex with _$Complex { const factory Complex.a(int value) = ComplexA; const factory Complex.b(double value) = ComplexB; }
For this specific case, we just have to add an abstract getter with the nearest common type :
abstract class Complex with _$Complex {
const factory Complex.a(int value) = ComplexA;
const factory Complex.b(double value) = ComplexB;
num get value;
}
from freezed.
Related Issues (20)
- Documenting the generated methods copyWith and toJson HOT 2
- Setting the flag `@Freezed(toJson: false)` creates an error in the generated freezed files when we define a custom `toJson`.
- Problem with fromJson in web app HOT 1
- Generics complicate self-referential class structure HOT 2
- Add support for required constructor parameters that are ignored by freezes HOT 1
- Why not integrate the FieldRename functionality from JsonSerializable into Freezed? HOT 1
- Why not integrate a annotation to rename JSON fields (like in JsonSerializable)? HOT 3
- Confusing legacy tag for "Union types and Sealed classes" HOT 5
- Switch from a model M1 to a model M2 HOT 1
- Arguments of a constant creation must be constant expressions. When adding custom converter with json_serializable HOT 2
- Add support for default value on copyWith
- Add default value for field on copyWith HOT 3
- LinkedHashMap, HashMap is mutable with @freezed HOT 1
- If the path does not start with the lib folder, is it ignored? HOT 1
- Support both analyzer versions HOT 2
- Using macros insted build_runner HOT 1
- freezed and macros HOT 1
- freezed 2.5.3 analyzer 6.5.0 problem HOT 8
- support makeCollectionsUnmodifiable in build.yaml
- Freezed 2.5.3 doesn't work with latest stable Flutter HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from freezed.