[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-9242":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":17,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":18,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":19,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":28,"readmeContent":29,"aiSummary":30,"trendingCount":16,"starSnapshotCount":16,"syncStatus":31,"lastSyncTime":32,"discoverSource":33},9242,"freezed","rrousselGit\u002Ffreezed","rrousselGit","Code generation for immutable classes that has a simple syntax\u002FAPI without compromising on the features.","https:\u002F\u002Fpub.dev\u002Fpackages\u002Ffreezed",null,"Dart",2176,300,13,108,0,4,29.44,false,"master",true,[23,24,25,26,27],"code-generator","dart","flutter","hacktoberfest","union-types","2026-06-12 02:02:04","[English](https:\u002F\u002Fgithub.com\u002FrrousselGit\u002Ffreezed\u002Fblob\u002Fmaster\u002Fpackages\u002Ffreezed\u002FREADME.md) | [한국어](https:\u002F\u002Fgithub.com\u002FrrousselGit\u002Ffreezed\u002Fblob\u002Fmaster\u002Fresources\u002Ftranslations\u002Fko_KR\u002FREADME.md) | [简体中文](https:\u002F\u002Fgithub.com\u002FrrousselGit\u002Ffreezed\u002Fblob\u002Fmaster\u002Fresources\u002Ftranslations\u002Fzh_CN\u002FREADME.md) | [日本語](https:\u002F\u002Fgithub.com\u002FrrousselGit\u002Ffreezed\u002Fblob\u002Fmaster\u002Fresources\u002Ftranslations\u002Fja_JP\u002FREADME.md) | [Tiếng Việt](https:\u002F\u002Fgithub.com\u002FrrousselGit\u002Ffreezed\u002Fblob\u002Fmaster\u002Fresources\u002Ftranslations\u002Fvi_VN\u002FREADME.md)\n\n![Build](https:\u002F\u002Fgithub.com\u002FrrousselGit\u002Ffreezed\u002Fworkflows\u002FBuild\u002Fbadge.svg)\n[![pub package](https:\u002F\u002Fimg.shields.io\u002Fpub\u002Fv\u002Ffreezed.svg)](https:\u002F\u002Fpub.dartlang.org\u002Fpackages\u002Ffreezed)\n\u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002FGSt793j6eT\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fdiscord\u002F765557403865186374.svg?logo=discord&color=blue\" alt=\"Discord\">\u003C\u002Fa>\n\n[\u003Cimg src=\"https:\u002F\u002Fraw.githubusercontent.com\u002FrrousselGit\u002Fprovider\u002Fmaster\u002Fresources\u002Fflutter_favorite.png\" width=\"200\" \u002F>](https:\u002F\u002Fflutter.dev\u002Fdocs\u002Fdevelopment\u002Fpackages-and-plugins\u002Ffavorites)\n\nWelcome to [Freezed], yet another code generator for data classes, tagged unions, nested classes and cloning.\n\n# Migration to 3.0.0\n\nTo migrate from 2.0.0 to 3.0.0, see [changelog](https:\u002F\u002Fgithub.com\u002FrrousselGit\u002Ffreezed\u002Fblob\u002Fmaster\u002Fpackages\u002Ffreezed\u002FCHANGELOG.md#300---2025-02-25) and our [migration guide](https:\u002F\u002Fgithub.com\u002FrrousselGit\u002Ffreezed\u002Fblob\u002Fmaster\u002Fpackages\u002Ffreezed\u002Fmigration_guide.md).\n\n# Motivation\n\nDart is awesome, but defining a \"model\" can be tedious. You have to:\n\n- Define a constructor + properties\n- Override `toString`, `operator ==`, `hashCode`\n- Implement a `copyWith` method to clone the object\n- Handle (de)serialization\n\nImplementing all of this can take hundreds of lines, which are error-prone\nand affect the readability of your model significantly.\n\nFreezed tries to fix that by implementing most of this for you, allowing you\nto focus on the definition of your model.\n\n| Before                                                                                                  | After                                                                                       |\n| ------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |\n| ![before](https:\u002F\u002Fraw.githubusercontent.com\u002FrrousselGit\u002Ffreezed\u002Frefs\u002Fheads\u002Fmaster\u002Fresources\u002Fbefore.png) | ![before](https:\u002F\u002Fraw.githubusercontent.com\u002FrrousselGit\u002Ffreezed\u002Fmaster\u002Fresources\u002Fafter.png) |\n\n# Index\n\n- [Migration to 3.0.0](#migration-to-300)\n- [Motivation](#motivation)\n- [Index](#index)\n- [How to use](#how-to-use)\n  - [Install](#install)\n    - [Disabling invalid\\_annotation\\_target warning and warning in generates files](#disabling-invalid_annotation_target-warning-and-warning-in-generates-files)\n  - [Run the generator](#run-the-generator)\n  - [Creating a Model using Freezed](#creating-a-model-using-freezed)\n    - [Primary constructors](#primary-constructors)\n      - [Adding getters and methods to our models](#adding-getters-and-methods-to-our-models)\n      - [Asserts](#asserts)\n      - [Default values](#default-values)\n      - [Non-constant default values](#non-constant-default-values)\n      - [Extending classes](#extending-classes)\n      - [Defining a mutable class instead of an immutable one](#defining-a-mutable-class-instead-of-an-immutable-one)\n      - [Allowing the mutation of Lists\u002FMaps\u002FSets](#allowing-the-mutation-of-listsmapssets)\n    - [Classic classes](#classic-classes)\n  - [How copyWith works](#how-copywith-works)\n    - [Going further: Deep copy](#going-further-deep-copy)\n  - [Decorators and comments](#decorators-and-comments)\n  - [FromJson\u002FToJson](#fromjsontojson)\n    - [fromJSON - classes with multiple constructors](#fromjson---classes-with-multiple-constructors)\n    - [Deserializing generic classes](#deserializing-generic-classes)\n  - [Union types](#union-types)\n    - [Shared properties](#shared-properties)\n    - [Using pattern matching to read non-shared properties](#using-pattern-matching-to-read-non-shared-properties)\n    - [Mixins and Interfaces for individual classes for union types](#mixins-and-interfaces-for-individual-classes-for-union-types)\n    - [Ejecting an individual union case](#ejecting-an-individual-union-case)\n      - [(Legacy) Pattern matching utilities](#legacy-pattern-matching-utilities)\n        - [When](#when)\n        - [Map](#map)\n  - [Configurations](#configurations)\n    - [Changing the behavior for a specific model](#changing-the-behavior-for-a-specific-model)\n    - [Changing the behavior for the entire project](#changing-the-behavior-for-the-entire-project)\n- [Utilities](#utilities)\n  - [IDE Extensions](#ide-extensions)\n    - [Freezed extension for VSCode](#freezed-extension-for-vscode)\n    - [Freezed extension for IntelliJ\u002FAndroid Studio](#freezed-extension-for-intellijandroid-studio)\n  - [Linting](#linting)\n  - [Third-party tools](#third-party-tools)\n    - [DartJ](#dartj)\n  - [Sponsors](#sponsors)\n\n# How to use\n\n## Install\n\nTo use [Freezed], you will need your typical [build_runner]\u002Fcode-generator setup.\\\nFirst, install [build_runner] and [Freezed] by adding them to your `pubspec.yaml` file:\n\nFor a Flutter project:\n\n```console\nflutter pub add \\\n  dev:build_runner \\\n  freezed_annotation \\\n  dev:freezed\n# if using freezed to generate fromJson\u002FtoJson, also add:\nflutter pub add json_annotation dev:json_serializable\n```\n\nFor a Dart project:\n\n```console\ndart pub add \\\n  dev:build_runner \\\n  freezed_annotation \\\n  dev:freezed\n# if using freezed to generate fromJson\u002FtoJson, also add:\ndart pub add json_annotation dev:json_serializable\n```\n\nThis installs three packages:\n\n- [build_runner](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fbuild_runner), the tool to run code-generators\n- [freezed], the code generator\n- [freezed_annotation](https:\u002F\u002Fpub.dev\u002Fpackages\u002Ffreezed_annotation), a package containing annotations for [freezed].\n\n### Disabling invalid_annotation_target warning and warning in generates files\n\nIf you plan on using [Freezed] in combination with `json_serializable`, recent\nversions of `json_serializable` and `meta` may require you to disable the\n`invalid_annotation_target` warning.\n\nTo do that, you can add the following to the `analysis_options.yaml` file\nat the root of your project:\n\n```yaml\nanalyzer:\n  errors:\n    invalid_annotation_target: ignore\n```\n\n## Run the generator\n\nTo run the code generator, execute the following command:\n\n```\ndart run build_runner watch -d\n```\n\nNote that like most code-generators, [Freezed] will need you to both import the annotation ([freezed_annotation])\nand use the `part` keyword on the top of your files.\n\nAs such, a file that wants to use [Freezed] will start with:\n\n```dart\nimport 'package:freezed_annotation\u002Ffreezed_annotation.dart';\n\npart 'my_file.freezed.dart';\n\n```\n\n**CONSIDER** also importing `package:flutter\u002Ffoundation.dart`.\\\nThe reason being, importing `foundation.dart` also imports classes to make an\nobject nicely readable in Flutter's devtool.\\\nIf you import `foundation.dart`, [Freezed] will automatically do it for you.\n\n## Creating a Model using Freezed\n\nFreezed offers two ways of creating data-classes:\n\n- [Primary constructors](#primary-constructors) ; where you define a constructor and Freezed generates the associated fields.\n  This is simulating the [Primary Constructor](https:\u002F\u002Fgithub.com\u002Fdart-lang\u002Flanguage\u002Fissues\u002F2364) using `factory`.\n- [Classic classes](#classic-classes), where you write a normal Dart class and Freezed only handles `toString\u002F==\u002FcopyWith`\n\n### Primary constructors\n\nFreezed implements Primary Constructors by relying on `factory` constructors.\nThe idea is, you define a `factory` and Freezed generates everything else:\n\n```dart\nimport 'package:freezed_annotation\u002Ffreezed_annotation.dart';\n\n\u002F\u002F required: associates our `main.dart` with the code generated by Freezed\npart 'main.freezed.dart';\n\u002F\u002F optional: Since our Person class is serializable, we must add this line.\n\u002F\u002F But if Person was not serializable, we could skip it.\npart 'main.g.dart';\n\n@freezed\nabstract class Person with _$Person {\n  const factory Person({\n    required String firstName,\n    required String lastName,\n    required int age,\n  }) = _Person;\n\n  factory Person.fromJson(Map\u003CString, Object?> json) => _$PersonFromJson(json);\n}\n```\n\nThe following snippet defines a model named `Person`:\n\n- `Person` has 3 properties: `firstName`, `lastName` and `age`\n- Because we are using `@freezed`, all of this class's properties are immutable.\n- Since we defined a `fromJson`, this class is de\u002Fserializable.\n  Freezed will add a `toJson` method for us.\n- Freezed will also automatically generate:\n  - a `copyWith` method, for cloning the object with different properties\n  - a `toString` override listing all the properties of the object\n  - an `operator ==` and `hashCode` override (since `Person` is immutable)\n\nFrom this example, we can notice a few things:\n\n- It is necessary to annotate our model with `@freezed` (or `@Freezed`\u002F`@unfreezed`, more about that later).  \n  This annotation is what tells Freezed to generate code for that class.\n\n- We must also apply a mixin with the name of our class, prefixed by `_$`.\n  This mixin is what defines the various properties\u002Fmethods of our object.\n\n- When defining a constructor in a Freezed class, we should use the `factory` keyword\n  as showcased (`const` is optional).  \n  The parameters of this constructor will be the list of all properties that this class contains.  \n  Parameters **don't** have to be named and required. Feel free to use\n  positional optional parameters if you want!\n\n#### Adding getters and methods to our models\n\nSometimes, you may want to manually define methods\u002Fproperties in our classes.  \nBut you will quickly notice that if you try to use primary constructors:\n\n```dart\n@freezed\nabstract class Person with _$Person {\n  const factory Person(String name, {int? age}) = _Person;\n\n  void method() {\n    print('hello world');\n  }\n}\n```\n\nthen it will fail with the error `The non-abstract class _$_Person is missing implementations for these members:`.\n\nFor that to work, we need to define a private empty constructor. That will enable the generated code to _extend\u002Fsubclass_ our class, instead of _implementing_ it (which is the default, and only inherits type, and not properties or methods):\n\n```dart\n@freezed\nabstract class Person with _$Person {\n  \u002F\u002F Added constructor. Must not have any parameter\n  const Person._();\n\n  const factory Person(String name, {int? age}) = _Person;\n\n  void method() {\n    print('hello world');\n  }\n}\n```\n\n#### Asserts\n\nDart does not allow adding `assert(...)` statements to a `factory` constructor.  \nAs such, to add asserts to your Freezed classes, you will need the `@Assert` decorator:\n\n```dart\n@freezed\nabstract class Person with _$Person {\n  @Assert('name.isNotEmpty', 'name cannot be empty')\n  const factory Person({required String name, int? age}) = _Person;\n}\n```\n\nAlternatively, you can specify a `MyClass._()` constructor:\n\n```dart\n@freezed\nabstract class Person with _$Person {\n  Person._({required this.name})\n    : assert(name.isNotEmpty, 'name cannot be empty');\n\n  factory Person({required String name, int? age}) = _Person;\n\n  @override\n  final String name;\n}\n```\n\n#### Default values\n\nSimilarly to asserts, Dart does not allow \"redirecting factory constructors\"\nto specify default values.\n\nAs such, if you want to specify default values for your properties,\nyou will need the `@Default` annotation:\n\n```dart\n@freezed\nabstract class Example with _$Example {\n  const factory Example([@Default(42) int value]) = _Example;\n}\n```\n\n**NOTE**:\\\nIf you are using serialization\u002Fdeserialization, this will automatically add\na `@JsonKey(defaultValue: \u003Csomething>)` for you.\n\n#### Non-constant default values\n\nIf using `@Default` is not enough, you have two options:\n\n- Either stop using primary constructors. See [Classic Classes](#classic-classes)\n- Add a `MyClass._()` constructor to initialize said value\n\nThe latter is particularly helpful when writing large models, as this doesn't require writing a lot of code just for one default values.\n\nOne example would be the following:\n\n```dart\n@freezed\nsealed class Response\u003CT> with _$Response\u003CT> {\n  \u002F\u002F We give \"time\" parameters a non-constant default\n  Response._({DateTime? time}) : time = time ?? DateTime.now();\n  \u002F\u002F Constructors may enable passing parameters to ._();\n  factory Response.data(T value, {DateTime? time}) = ResponseData;\n  \u002F\u002F If ._ parameters are named and optional, factory constructors are not required to specify it\n  factory Response.error(Object error) = ResponseError;\n\n  @override\n  final DateTime time;\n}\n```\n\nIn this example, the field `time` is defaulting to `DateTime.now()`.\n\n#### Extending classes\n\nYou may want to have your Freezed class extend another class.\nUnfortunately, `factory` does not allow specifying `super(...)`.\n\nAs such, one workaround is to specify the `MyClass._()` again, similarly\nto how we used it for non-constant default values. Here's an example:\n\n```dart\nclass Subclass {\n  const Subclass.name(this.value);\n\n  final int value;\n}\n\n@freezed\nabstract class MyFreezedClass extends Subclass with _$MyFreezedClass {\n  \u002F\u002F We can receive parameters in this constructor, which we can use with `super.field`\n  const MyFreezedClass._(super.value) : super.name();\n\n  const factory MyFreezedClass(int value, \u002F* other fields *\u002F) = _MyFreezedClass;\n}\n```\n\nThis syntax gives full control over inheritance.  \nOf course, you can also opt-out of `factory` constructors and write normal classes.\nSee [Classic Classes](#classic-classes).\n\nIn general, this workaround makes more sense for [Unions](#union-types), where\nwe have more than one `factory` constructor.\n\n#### Defining a mutable class instead of an immutable one\n\nSo far, we've seen how to define a model where all of its properties are `final`;\nbut you may want to define mutable properties in your model.\n\nFreezed supports this, by replacing the `@freezed` annotation with `@unfreezed`:\n\n```dart\n@unfreezed\nabstract class Person with _$Person {\n  factory Person({\n    required String firstName,\n    required String lastName,\n    required final int age,\n  }) = _Person;\n\n  factory Person.fromJson(Map\u003CString, Object?> json) => _$PersonFromJson(json);\n}\n```\n\nThis defines a model mostly identical to our previous snippets, but with the following\ndifferences:\n\n- `firstName` and `lastName` are now mutable. As such, we can write:\n\n  ```dart\n  void main() {\n    var person = Person(firstName: 'John', lastName: 'Smith', age: 42);\n\n    person.firstName = 'Mona';\n    person.lastName = 'Lisa';\n  }\n  ```\n\n- `age` is still immutable, because we explicitly marked the property as `final`.\n- `Person` no-longer has a custom ==\u002FhashCode implementation:\n\n  ```dart\n  void main() {\n    var john = Person(firstName: 'John', lastName: 'Smith', age: 42);\n    var john2 = Person(firstName: 'John', lastName: 'Smith', age: 42);\n\n    print(john == john2); \u002F\u002F false\n  }\n  ```\n\n- Of course, since our `Person` class is mutable, it is no-longer possible\n  to instantiate it using `const`.\n\n#### Allowing the mutation of Lists\u002FMaps\u002FSets\n\nBy default when using `@freezed` (but not `@unfreezed`), properties of type `List`\u002F`Map`\u002F`Set`\nare transformed to be immutable.\n\nThis means that writing the following will cause a runtime exception:\n\n```dart\n@freezed\nabstract class Example with _$Example {\n  factory Example(List\u003Cint> list) = _Example;\n}\n\nvoid main() {\n  var example = Example([]);\n  example.list.add(42); \u002F\u002F throws because we are mutating a collection\n}\n```\n\nThat behavior can be disabled by writing:\n\n```dart\n@Freezed(makeCollectionsUnmodifiable: false)\nabstract class Example with _$Example {\n  factory Example(List\u003Cint> list) = _Example;\n}\n\nvoid main() {\n  var example = Example([]);\n  example.list.add(42); \u002F\u002F OK\n}\n```\n\n### Classic classes\n\nInstead of primary constructors, you can write normal Dart classes.\n\nIn this scenario, write a typical constructor + fields combo as you normally would:\n\n```dart\nimport 'package:freezed_annotation\u002Ffreezed_annotation.dart';\n\n\u002F\u002F required: associates our `main.dart` with the code generated by Freezed\npart 'main.freezed.dart';\n\u002F\u002F optional: Since our Person class is serializable, we must add this line.\n\u002F\u002F But if Person was not serializable, we could skip it.\npart 'main.g.dart';\n\n@freezed\n@JsonSerializable()\nclass Person with _$Person {\n  const Person({\n    required this.firstName,\n    required this.lastName,\n    required this.age,\n  });\n\n  @override\n  final String firstName;\n  @override\n  final String lastName;\n  @override\n  final int age;\n\n  factory Person.fromJson(Map\u003CString, Object?> json)\n      => _$PersonFromJson(json);\n\n  Map\u003CString, Object?> toJson() => _$PersonToJson(this);\n}\n```\n\nIn this scenario, Freezed will generate `copyWith`\u002F`toString`\u002F`==`\u002F`hashCode`,\nbut won't do anything related to JSON encoding (hence why you need to manually add `@JsonSerializable`).\n\nThis syntax has the benefit of enabling advanced constructor logic, such as\ninheritance or non-constant default values.\n\n## How copyWith works\n\nAs explained before, when defining a model using Freezed, then the code-generator\nwill automatically generate a `copyWith` method for us.  \nThis method is used to clone an object with different values.\n\nFor example if we define:\n\n```dart\n@freezed\nabstract class Person with _$Person {\n  factory Person(String name, int? age) = _Person;\n}\n```\n\nThen we could write:\n\n```dart\nvoid main() {\n  var person = Person('Remi', 24);\n\n  \u002F\u002F `age` not passed, its value is preserved\n  print(person.copyWith(name: 'Dash')); \u002F\u002F Person(name: Dash, age: 24)\n  \u002F\u002F `age` is set to `null`\n  print(person.copyWith(age: null)); \u002F\u002F Person(name: Remi, age: null)\n}\n```\n\nNotice Freezed supports `person.copyWith(age: null)`.\n\n### Going further: Deep copy\n\nWhile `copyWith` is very powerful in itself, it becomes inconvenient on more complex objects.\n\nConsider the following classes:\n\n```dart\n@freezed\nabstract class Company with _$Company {\n  const factory Company({String? name, required Director director}) = _Company;\n}\n\n@freezed\nabstract class Director with _$Director {\n  const factory Director({String? name, Assistant? assistant}) = _Director;\n}\n\n@freezed\nabstract class Assistant with _$Assistant {\n  const factory Assistant({String? name, int? age}) = _Assistant;\n}\n```\n\nThen, from a reference on `Company`, we may want to perform changes on `Assistant`.\\\nFor example, to change the `name` of an assistant, using `copyWith` we would have to write:\n\n```dart\nCompany company;\n\nCompany newCompany = company.copyWith(\n  director: company.director.copyWith(\n    assistant: company.director.assistant.copyWith(\n      name: 'John Smith',\n    ),\n  ),\n);\n```\n\nThis _works_, but is relatively verbose with a lot of duplicates.\\\nThis is where we could use [Freezed]'s \"deep copy\".\n\nIf a Freezed model contains properties that are also Freezed models, then\nthe code-generator will offer an alternate syntax to the previous example:\n\n```dart\nCompany company;\n\nCompany newCompany = company.copyWith.director.assistant(name: 'John Smith');\n```\n\nThis snippet will achieve strictly the same result as the previous snippet\n(creating a new company with an updated assistant name), but no longer has duplicates.\n\nGoing deeper in this syntax, if instead, we wanted to change the director's name\nthen we could write:\n\n```dart\nCompany company;\nCompany newCompany = company.copyWith.director(name: 'John Doe');\n```\n\nOverall, based on the definitions of `Company`\u002F`Director`\u002F`Assistant` mentioned above,\nall the following \"copy\" syntaxes will work:\n\n```dart\nCompany company;\n\ncompany = company.copyWith(name: 'Google', director: Director(...));\ncompany = company.copyWith.director(name: 'Larry', assistant: Assistant(...));\n```\n\n**Null consideration**\n\nSome objects may also be `null`. For example, using our `Company` class,\nthen `Director`'s `assistant` may be `null`.\n\nAs such, writing:\n\n```dart\nCompany company = Company(name: 'Google', director: Director(assistant: null));\nCompany newCompany = company.copyWith.director.assistant(name: 'John');\n```\n\ndoesn't make sense.  \nWe can't change the assistant's name if there is no assistant to begin with.\n\nIn that situation, `company.copyWith.director.assistant` will return `null`,\ncausing our code to fail to compile.\n\nTo fix it, we can use the `?.call` operator and write:\n\n```dart\nCompany? newCompany = company.copyWith.director.assistant?.call(name: 'John');\n```\n\n## Decorators and comments\n\n[Freezed] supports property and class level decorators\u002Fdocumentation by\ndecorating\u002Fdocumenting their respective parameter and constructor definition.\n\nConsider:\n\n```dart\n@freezed\nabstract class Person with _$Person {\n  const factory Person({\n    String? name,\n    int? age,\n    Gender? gender,\n  }) = _Person;\n}\n```\n\nIf you want to document `name`, you can do:\n\n```dart\n@freezed\nabstract class Person with _$Person {\n  const factory Person({\n    \u002F\u002F\u002F The name of the user.\n    \u002F\u002F\u002F\n    \u002F\u002F\u002F Must not be null\n    String? name,\n    int? age,\n    Gender? gender,\n  }) = _Person;\n}\n```\n\nIf you want to mark the property `gender` as `@deprecated`, then you can do:\n\n```dart\n@freezed\nabstract class Person with _$Person {\n  const factory Person({\n    String? name,\n    int? age,\n    @deprecated Gender? gender,\n  }) = _Person;\n}\n```\n\nThis will deprecate both:\n\n- The constructor\n  ```dart\n  Person(gender: Gender.something); \u002F\u002F gender is deprecated\n  ```\n- The generated class's constructor:\n  ```dart\n  _Person(gender: Gender.something); \u002F\u002F gender is deprecated\n  ```\n- the property:\n  ```dart\n  Person person;\n  print(person.gender); \u002F\u002F gender is deprecated\n  ```\n- the `copyWith` parameter:\n  ```dart\n  Person person;\n  person.copyWith(gender: Gender.something); \u002F\u002F gender is deprecated\n  ```\n\nSimilarly, if you want to decorate the generated class you can decorate the\ndefining factory constructor.\n\nAs such, to deprecate `_Person`, you could do:\n\n```dart\n@freezed\nabstract class Person with _$Person {\n  @deprecated\n  const factory Person({\n    String? name,\n    int? age,\n    Gender? gender,\n  }) = _Person;\n}\n```\n\n## FromJson\u002FToJson\n\nWhile [Freezed] will not generate your typical `fromJson`\u002F`toJson` by itself, it knows\nwhat [json_serializable] is.\n\nMaking a class compatible with [json_serializable] is very straightforward.\n\nConsider this snippet:\n\n```dart\nimport 'package:freezed_annotation\u002Ffreezed_annotation.dart';\n\npart 'model.freezed.dart';\n\n@freezed\nsealed class Model with _$Model {\n  factory Model.first(String a) = First;\n  factory Model.second(int b, bool c) = Second;\n}\n```\n\nThe changes necessary to make it compatible with [json_serializable] consists of two lines:\n\n- a new `part`: `part 'model.g.dart';`\n- a new constructor on the targeted class: `factory Model.fromJson(Map\u003CString, dynamic> json) => _$ModelFromJson(json);`\n\nThe end result is:\n\n```dart\nimport 'package:freezed_annotation\u002Ffreezed_annotation.dart';\n\npart 'model.freezed.dart';\npart 'model.g.dart';\n\n@freezed\nsealed class Model with _$Model {\n  factory Model.first(String a) = First;\n  factory Model.second(int b, bool c) = Second;\n\n  factory Model.fromJson(Map\u003CString, dynamic> json) => _$ModelFromJson(json);\n}\n```\n\nDon't forget to add `json_serializable` to your `pubspec.yaml` file:\n\n```yaml\ndev_dependencies:\n  json_serializable:\n```\n\nThat's it!\\\nWith these changes, [Freezed] will automatically ask [json_serializable] to generate all the necessary\n`fromJson`\u002F`toJson`.\n\n**Note**:  \nFreezed will only generate a fromJson if the factory is using `=>`.\n\n### fromJSON - classes with multiple constructors\n\nFor classes with multiple constructors, [Freezed] will check the JSON response\nfor a string element called `runtimeType` and choose the constructor to use based\non its value. For example, given the following constructors:\n\n```dart\n@freezed\nsealed class MyResponse with _$MyResponse {\n  const factory MyResponse(String a) = MyResponseData;\n  const factory MyResponse.special(String a, int b) = MyResponseSpecial;\n  const factory MyResponse.error(String message) = MyResponseError;\n\n  factory MyResponse.fromJson(Map\u003CString, dynamic> json) => _$MyResponseFromJson(json);\n}\n```\n\nThen [Freezed] will use each JSON object's `runtimeType` to choose the constructor as follows:\n\n```json\n[\n  {\n    \"runtimeType\": \"default\",\n    \"a\": \"This JSON object will use constructor MyResponse()\"\n  },\n  {\n    \"runtimeType\": \"special\",\n    \"a\": \"This JSON object will use constructor MyResponse.special()\",\n    \"b\": 42\n  },\n  {\n    \"runtimeType\": \"error\",\n    \"message\": \"This JSON object will use constructor MyResponse.error()\"\n  }\n]\n```\n\nYou can customize key and value with something different\nusing `@Freezed` and `@FreezedUnionValue` decorators:\n\n```dart\n@Freezed(unionKey: 'type', unionValueCase: FreezedUnionCase.pascal)\nsealed class MyResponse with _$MyResponse {\n  const factory MyResponse(String a) = MyResponseData;\n\n  @FreezedUnionValue('SpecialCase')\n  const factory MyResponse.special(String a, int b) = MyResponseSpecial;\n\n  const factory MyResponse.error(String message) = MyResponseError;\n\n  factory MyResponse.fromJson(Map\u003CString, dynamic> json) =>\n      _$MyResponseFromJson(json);\n}\n```\n\nwhich would update the previous json to:\n\n```json\n[\n  {\n    \"type\": \"Default\",\n    \"a\": \"This JSON object will use constructor MyResponse()\"\n  },\n  {\n    \"type\": \"SpecialCase\",\n    \"a\": \"This JSON object will use constructor MyResponse.special()\",\n    \"b\": 42\n  },\n  {\n    \"type\": \"Error\",\n    \"message\": \"This JSON object will use constructor MyResponse.error()\"\n  }\n]\n```\n\nIf you want to customize key and value for all the classes, you can specify it inside your\n`build.yaml` file, for example:\n\n```yaml\ntargets:\n  $default:\n    builders:\n      freezed:\n        options:\n          union_key: type\n          union_value_case: pascal\n```\n\nIf you don't control the JSON response, then you can implement a custom converter.\nYour custom converter will need to implement its own logic for determining which\nconstructor to use.\n\n```dart\nclass MyResponseConverter implements JsonConverter\u003CMyResponse, Map\u003CString, dynamic>> {\n  const MyResponseConverter();\n\n  @override\n  MyResponse fromJson(Map\u003CString, dynamic> json) {\n    \u002F\u002F type data was already set (e.g. because we serialized it ourselves)\n    if (json['runtimeType'] != null) {\n      return MyResponse.fromJson(json);\n    }\n    \u002F\u002F you need to find some condition to know which type it is. e.g. check the presence of some field in the json\n    if (isTypeData) {\n      return MyResponseData.fromJson(json);\n    } else if (isTypeSpecial) {\n      return MyResponseSpecial.fromJson(json);\n    } else if (isTypeError) {\n      return MyResponseError.fromJson(json);\n    } else {\n      throw Exception('Could not determine the constructor for mapping from JSON');\n    }\n }\n\n  @override\n  Map\u003CString, dynamic> toJson(MyResponse data) => data.toJson();\n}\n```\n\nTo then apply your custom converter pass the decorator to a constructor parameter.\n\n```dart\n@freezed\nabstract class MyModel with _$MyModel {\n  const factory MyModel(@MyResponseConverter() MyResponse myResponse) = MyModelData;\n\n  factory MyModel.fromJson(Map\u003CString, dynamic> json) => _$MyModelFromJson(json);\n}\n```\n\nBy doing this, json serializable will use `MyResponseConverter.fromJson()` and `MyResponseConverter.toJson()` to convert `MyResponse`.\n\nYou can also use a custom converter on a constructor parameter contained in a `List`.\n\n```dart\n@freezed\nabstract class MyModel with _$MyModel {\n  const factory MyModel(@MyResponseConverter() List\u003CMyResponse> myResponse) = MyModelData;\n\n  factory MyModel.fromJson(Map\u003CString, dynamic> json) => _$MyModelFromJson(json);\n}\n```\n\n**Note**:  \nIn order to serialize nested lists of freezed objects, you are supposed to either\nspecify a `@JsonSerializable(explicitToJson: true)` or change `explicit_to_json`\ninside your `build.yaml` file ([see the documentation](https:\u002F\u002Fgithub.com\u002Fgoogle\u002Fjson_serializable.dart\u002Ftree\u002Fmaster\u002Fjson_serializable#build-configuration)).\n\n### Deserializing generic classes\n\nIn order to de\u002Fserialize generic typed freezed objects, you can enable `genericArgumentFactories`.  \nAll you need to do is to change the signature of the `fromJson` method and add `genericArgumentFactories: true` to the freezed configuration.\n\n```dart\n@Freezed(genericArgumentFactories: true)\nsealed class ApiResponse\u003CT> with _$ApiResponse\u003CT> {\n  const factory ApiResponse.data(T data) = ApiResponseData;\n  const factory ApiResponse.error(String message) = ApiResponseError;\n\n  factory ApiResponse.fromJson(Map\u003CString, dynamic> json, T Function(Object?) fromJsonT) => _$ApiResponseFromJson(json, fromJsonT);\n}\n```\n\nAlternatively, you can enable `genericArgumentFactories` for the whole project by modifying your `build.yaml` file to include the following:\n\n```yaml\ntargets:\n  $default:\n    builders:\n      freezed:\n        options:\n          generic_argument_factories: true\n```\n\n**What about `@JsonKey` annotation?**\n\nAll decorators passed to a constructor parameter are \"copy-pasted\" to the generated\nproperty too.\\\nAs such, you can write:\n\n```dart\n@freezed\nabstract class Example with _$Example {\n  factory Example(@JsonKey(name: 'my_property') String myProperty) = _Example;\n\n  factory Example.fromJson(Map\u003CString, dynamic> json) => _$ExampleFromJson(json);\n}\n```\n\n**What about `@JsonSerializable` annotation?**\n\nYou can pass `@JsonSerializable` annotation by placing it over constructor e.g.:\n\n```dart\n@freezed\nabstract class Example with _$Example {\n  @JsonSerializable(explicitToJson: true)\n  factory Example(@JsonKey(name: 'my_property') SomeOtherClass myProperty) = _Example;\n\n  factory Example.fromJson(Map\u003CString, dynamic> json) => _$ExampleFromJson(json);\n}\n```\n\nIf you want to define some custom json_serializable flags for all the classes (e.g. `explicit_to_json` or `any_map`) you can do it via `build.yaml` file as described [here](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fjson_serializable#build-configuration).\n\nSee also the [decorators](#decorators-and-comments) section\n\n## Union types\n\nComing from other languages, you may be used to features like \"union types,\" \"sealed classes,\" and pattern matching.\n\nThese are powerful tools in combination with a type system, but it isn't particularly ergonomic to use them in Dart.\n\nBut fear not, [Freezed] supports them, generating a few utilities to help you!\n\nLong story short, in any Freezed class, you can write multiple constructors:\n\n```dart\n@freezed\nsealed class Union with _$Union {\n  const factory Union.data(int value) = Data;\n  const factory Union.loading() = Loading;\n  const factory Union.error([String? message]) = Error;\n}\n```\n\nBy doing this, our model now can be in different mutually exclusive states.\n\nIn particular, this snippet defines a model `Union`, and that model has 3 possible states:\n\n- data\n- loading\n- error\n\nNote how we gave meaningful names to the right hand of the factory constructors we defined.\nThey will come in handy later.\n\nOne thing you may also notice is that with this example, we can no longer write code such as:\n\n```dart\nvoid main() {\n  Union union = Union.data(42);\n\n  print(union.value); \u002F\u002F compilation error: property value does not exist\n}\n```\n\nWe'll see why in the following section.\n\n### Shared properties\n\nWhen defining multiple constructors, you will lose the ability to read properties that are not common to all constructors:\n\nFor example, if you write:\n\n```dart\n@freezed\nsealed class Example with _$Example {\n  const factory Example.person(String name, int age) = Person;\n  const factory Example.city(String name, int population) = City;\n}\n```\n\nThen you will be unable to read `age` and `population` directly:\n\n```dart\nvar example = Example.person('Remi', 24);\nprint(example.age); \u002F\u002F does not compile!\n```\n\nOn the other hand, you **can** read properties that are defined on all constructors.\nFor example, the `name` variable is common to both `Example.person` and `Example.city` constructors.\n\nAs such we can write:\n\n```dart\nvar example = Example.person('Remi', 24);\nprint(example.name); \u002F\u002F Remi\nexample = Example.city('London', 8900000);\nprint(example.name); \u002F\u002F London\n```\n\nThe same logic can be applied to `copyWith` too.  \nWe can use `copyWith` with properties defined on all constructors:\n\n```dart\nvar example = Example.person('Remi', 24);\nprint(example.copyWith(name: 'Dash')); \u002F\u002F Example.person(name: Dash, age: 24)\n\nexample = Example.city('London', 8900000);\nprint(example.copyWith(name: 'Paris')); \u002F\u002F Example.city(name: Paris, population: 8900000)\n```\n\nOn the other hand, properties that are unique to a specific constructor aren't available:\n\n```dart\nvar example = Example.person('Remi', 24);\n\nexample.copyWith(age: 42); \u002F\u002F compilation error, parameter `age` does not exist\n```\n\nTo solve this problem, we need check the state of our object using what we call \"pattern matching\".\n\n### Using pattern matching to read non-shared properties\n\nFor this section, let's consider the following union:\n\n```dart\n@freezed\nsealed class Example with _$Example {\n  const factory Example.person(String name, int age) = Person;\n  const factory Example.city(String name, int population) = City;\n}\n```\n\nLet's see how we can use pattern matching to read the content of an `Example` instance.\n\nFor this, you should use Dart’s built-in pattern matching using `switch`:\n\n```dart\nswitch (example) {\n  Person(:final name) => print('Person $name'),\n  City(:final population) => print('City ($population)'),\n}\n```\n\nAlternatively, you could use an `if`-`case` statement:\n\n```dart\nif (example case Person(:final name)) {\n  print('Person $name');\n} else if (example case City(:final population)) {\n  print('City ($population)');\n}\n```\n\nYou could also use `is`\u002F`as` to cast an `Example` variable into either a `Person` or a `City`, but this is heavily discouraged. Use one of the other two options.\n\n### Mixins and Interfaces for individual classes for union types\n\nWhen you have multiple types in the same class you might want one of those\ntypes to implement an interface or mixin a class. You can do that using the\n`@Implements` or `@With` decorators respectively. In the following example\n`City` implements `GeographicArea`.\n\n```dart\nabstract class GeographicArea {\n  int get population;\n  String get name;\n}\n\n@freezed\nsealed class Example with _$Example {\n  const factory Example.person(String name, int age) = Person;\n\n  @Implements\u003CGeographicArea>()\n  const factory Example.city(String name, int population) = City;\n}\n```\n\nThis also works for implementing or mixing in generic classes e.g.\n`AdministrativeArea\u003CHouse>` except when the class has a generic type parameter\ne.g. `AdministrativeArea\u003CT>`. In this case freezed will generate correct code\nbut dart will throw a load error on the annotation declaration when compiling.\nTo avoid this you should use the `@Implements.fromString` and\n`@With.fromString` decorators as follows:\n\n```dart\nabstract class GeographicArea {}\nabstract class House {}\nabstract class Shop {}\nabstract class AdministrativeArea\u003CT> {}\n\n@freezed\nsealed class Example\u003CT> with _$Example\u003CT> {\n  const factory Example.person(String name, int age) = Person\u003CT>;\n\n  @With.fromString('AdministrativeArea\u003CT>')\n  const factory Example.street(String name) = Street\u003CT>;\n\n  @With\u003CHouse>()\n  @Implements\u003CShop>()\n  @Implements\u003CGeographicArea>()\n  @Implements.fromString('AdministrativeArea\u003CT>')\n  const factory Example.city(String name, int population) = City\u003CT>;\n}\n```\n\n**Note**: You need to make sure that you comply with the interface\nrequirements by implementing all the abstract members. If the interface\nhas no members or just fields, you can fulfill the interface contract by\nadding them to the union type's constructor. Keep in mind that if\nthe interface defines a method or a getter, that you implement in the\nclass, you need to use the\n[Adding getters and methods to our models](#adding-getters-and-methods-to-our-models) instructions.\n\n**Note 2**: You cannot use `@With`\u002F`@Implements` with freezed classes.\nFreezed classes can neither be extended nor implemented.\n\n### Ejecting an individual union case\n\nTo have fine-grained control over your models, Freezed offer the ability to manually write a subclass of a union.\n\nConsider:\n\n```dart\n@freezed\nsealed class Result\u003CT> with _$Result {\n  factory Result.data(T data) = ResultData;\n  factory Result.error(Object error) = ResultError;\n}\n```\n\nNow, let's say we wanted to write `ResultData` ourselves. For that, simply\ndefine a `ResultData` class in the same file:\n\n```dart\n@freezed\nsealed class Result\u003CT> with _$Result {\n  factory Result.data(T data) = ResultData;\n  factory Result.error(Object error) = ResultError;\n}\n\nclass ResultData\u003CT> implements Result\u003CT> {\n  \u002F\u002F TODO: implement Result\u003CT>\n}\n```\n\nNote that the extracted class can be a Freezed class too!\n\n```dart\n@freezed\nsealed class Result\u003CT> with _$Result\u003CT> {\n  const Result._();\n  const factory Result.data(T data) = ResultData;\n  const factory Result.error(Object error) = ResultError;\n}\n\n\u002F\u002F TODO maybe add some methods unique to ResultData\n@freezed\nabstract class ResultData\u003CT> extends Result\u003CT> with _$ResultData\u003CT> {\n  const factory ResultData(T data) = _ResultData;\n  const ResultData._() : super._();\n}\n```\n\n#### (Legacy) Pattern matching utilities\n\n> [!WARNING]\n> As of Dart 3, Dart now has built-in pattern-matching using sealed classes.\n> As such, you no-longer need to rely on Freezed's generated methods for pattern matching.\n> Instead of using `when`\u002F`map`, use the official Dart syntax.\n>\n> The references to `when`\u002F`map` are kept for users who have yet to\n> migrate to Dart 3.\n> But in the long term, you should stop relying on them and migrate to `switch` expressions.\n\n##### When\n\nThe [when] method is the equivalent to pattern matching with destructuring.  \nThe prototype of the method depends on the constructors defined.\n\nFor example, with:\n\n```dart\n@freezed\nsealed class Union with _$Union {\n  const factory Union(int value) = Data;\n  const factory Union.loading() = Loading;\n  const factory Union.error([String? message]) = ErrorDetails;\n}\n```\n\nThen [when] will be:\n\n```dart\nvar union = Union(42);\n\nprint(\n  union.when(\n    (int value) => 'Data $value',\n    loading: () => 'loading',\n    error: (String? message) => 'Error: $message',\n  ),\n); \u002F\u002F Data 42\n```\n\nWhereas if we defined:\n\n```dart\n@freezed\nsealed class Model with _$Model {\n  factory Model.first(String a) = First;\n  factory Model.second(int b, bool c) = Second;\n}\n```\n\nThen [when] will be:\n\n```dart\nvar model = Model.first('42');\n\nprint(\n  model.when(\n    first: (String a) => 'first $a',\n    second: (int b, bool c) => 'second $b $c'\n  ),\n); \u002F\u002F first 42\n```\n\nNotice how each callback matches with a constructor's name and prototype.\n\n##### Map\n\nThe [map] methods are equivalent to [when], but **without** destructuring.\n\nConsider this class:\n\n```dart\n@freezed\nsealed class Model with _$Model {\n  factory Model.first(String a) = First;\n  factory Model.second(int b, bool c) = Second;\n}\n```\n\nWith such class, while [when] will be:\n\n```dart\nvar model = Model.first('42');\n\nprint(\n  model.when(\n    first: (String a) => 'first $a',\n    second: (int b, bool c) => 'second $b $c'\n  ),\n); \u002F\u002F first 42\n```\n\n[map] will instead be:\n\n```dart\nvar model = Model.first('42');\n\nprint(\n  model.map(\n    first: (First value) => 'first ${value.a}',\n    second: (Second value) => 'second ${value.b} ${value.c}'\n  ),\n); \u002F\u002F first 42\n```\n\nThis can be useful if you want to do complex operations, like [copyWith]\u002F`toString` for example:\n\n```dart\nvar model = Model.second(42, false)\nprint(\n  model.map(\n    first: (value) => value,\n    second: (value) => value.copyWith(c: true),\n  )\n); \u002F\u002F Model.second(b: 42, c: true)\n```\n\n## Configurations\n\nFreezed offers various options to customize the generated code. To do so, there are two possibilities:\n\n### Changing the behavior for a specific model\n\nIf you want to customize the generated code for only one specific class,\nyou can do so by using a different annotation:\n\n```dart\n@Freezed()\nabstract class Person with _$Person {\n  factory Person(String name, int age) = _Person;\n}\n```\n\nBy doing so, you can now pass various parameters to `@Freezed` to change the output:\n\n```dart\n@Freezed(\n  \u002F\u002F Disable the generation of copyWith\u002F==\n  copyWith: false,\n  equal: false,\n)\n abstract class Person with _$Person {...}\n```\n\nTo view all the possibilities, see the documentation of `@Freezed`: \u003Chttps:\u002F\u002Fpub.dev\u002Fdocumentation\u002Ffreezed_annotation\u002Flatest\u002Ffreezed_annotation\u002FFreezed-class.html>\n\n### Changing the behavior for the entire project\n\nInstead of applying your modification to a single class, you may want to apply it to\nall Freezed models at the same time.\n\nYou can do so by customizing a file called `build.yaml`  \nThis file is an optional configuration file that should be placed next to your `pubspec.yaml`:\n\n```\nmy_project_folder\u002F\n  pubspec.yaml\n  build.yaml\n  lib\u002F\n```\n\nThere, you will be able to change the same options as the options found in `@Freezed` (see above)\nby writing:\n\n```yaml\ntargets:\n  $default:\n    builders:\n      freezed:\n        options:\n          # Tells Freezed to format .freezed.dart files.\n          # This can significantly slow down code-generation.\n          # Disabling formatting will only work when opting into Dart 3.7 as a minimum\n          # in your project SDK constraints.\n          format: true\n          # Disable the generation of copyWith\u002F== for the entire project\n          copy_with: false\n          equal: false\n```\n\n# Utilities\n\n## IDE Extensions\n\n### Freezed extension for VSCode\n\nThe [Freezed](https:\u002F\u002Fmarketplace.visualstudio.com\u002Fitems?itemName=blaxou.freezed) extension might help you work faster with freezed. For example :\n\n- Use \u003Ckbd>Ctrl+Shift+B\u003C\u002Fkbd> (\u003Ckbd>Cmd+Shift+B\u003C\u002Fkbd> on Mac) to quickly build using `build_runner`.\n- Quickly generate a Freezed class by using \u003Ckbd>Ctrl+Shift+P\u003C\u002Fkbd> (\u003Ckbd>Cmd+Shift+P\u003C\u002Fkbd> on Mac)> `Generate Freezed class`.\n\n### Freezed extension for IntelliJ\u002FAndroid Studio\n\nYou can get Live Templates for boiler plate code [here](https:\u002F\u002Fgithub.com\u002FTinhorn\u002Ffreezed_intellij_live_templates).\n\nExample:\n\n- type **freezedClass** and press \u003Ckbd>Tab\u003C\u002Fkbd> to generate a freezed class\n  ```dart\n  @freezed\n  class Demo with _$Demo {\n  }\n  ```\n- type **freezedFromJson** and press \u003Ckbd>Tab\u003C\u002Fkbd> to generate the fromJson method for json_serializable\n  ```dart\n  factory Demo.fromJson(Map\u003CString, dynamic> json) => _$DemoFromJson(json);\n  ```\n\n## Linting\n\nYou can add `freezed` specific linting rules that provide helpful utilities and catch common mistakes when creating `freezed` classes.\n\nAdd [`custom_lint`](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fcustom_lint) and `freezed_lint` to your `pubspec.yaml`:\n\n```console\ndart pub add dev:custom_lint\ndart pub add dev:freezed_lint\n```\n\nAlso add `custom_lint` to your `analysis_options.yaml`:\n\n```yaml\nanalyzer:\n  plugins:\n    - custom_lint\n```\n\n## Third-party tools\n\nThis part contains community-made tools which integrate with Freezed.\n\n### DartJ\n\n[DartJ](https:\u002F\u002Fdartj.web.app\u002F#\u002F) is Flutter application, made by [**@ttpho**](https:\u002F\u002Fgithub.com\u002Fttpho), which will generate the Freezed classes from a JSON payload.\n\nExample:\n\n\u003Chttps:\u002F\u002Fgithub.com\u002Fttpho\u002Fttpho\u002Fassets\u002F3994863\u002F5d529258-c02c-4066-925e-ca2ffc68a804>\n\n## Sponsors\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fraw.githubusercontent.com\u002FrrousselGit\u002Ffreezed\u002Fmaster\u002Fsponsorkit\u002Fsponsors.svg\">\n    \u003Cimg src='https:\u002F\u002Fraw.githubusercontent.com\u002FrrousselGit\u002Ffreezed\u002Fmaster\u002Fsponsorkit\u002Fsponsors.svg'\u002F>\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\n[build_runner]: https:\u002F\u002Fpub.dev\u002Fpackages\u002Fbuild_runner\n[freezed]: https:\u002F\u002Fpub.dartlang.org\u002Fpackages\u002Ffreezed\n[freezed_annotation]: https:\u002F\u002Fpub.dartlang.org\u002Fpackages\u002Ffreezed_annotation\n[json_serializable]: https:\u002F\u002Fpub.dev\u002Fpackages\u002Fjson_serializable\n","Freezed 是一个用于生成不可变类的代码生成工具，它提供了一个简洁的语法\u002FAPI，同时不牺牲功能特性。该项目支持Dart语言，并且非常适合Flutter开发者使用。通过Freezed，用户可以自动生成包括构造函数、属性、`toString`、`operator ==`、`hashCode`方法以及`copyWith`克隆方法等在内的模型代码，极大地简化了定义数据模型的过程。此外，Freezed还支持联合类型（union types），使得处理复杂的数据结构变得更加容易。无论是对于需要频繁修改对象状态的应用场景还是希望提高代码可读性和维护性的开发项目来说，Freezed都是一个非常实用的选择。",2,"2026-06-11 03:21:50","top_language"]