I have known function typedefs in Dart for a long time. They are also explained in answers to this question.
Now, I have heard about non-function type aliases (or non-function typedefs) coming to Dart.
I am wondering two things:
Typedef in Dart is used to create a user-defined identity (alias) for a function, and we can use that identity in place of the function in the program code. When we use typedef we can define the parameters of the function.
How to Using typedef for Functions: The typedef keyword was at first made in Dart 1 to allude to functions. In Dart 1, if you need to utilize a function as a variable, field, or boundary, you need to make a typedef first. To utilize a type alias, you just need to relegate the function mark to a typedef.
A typedef, or function-type alias, gives a function type a name that you can use when declaring fields and return types. So in today’s article, we will walk through what is a typedef in Dart. What is a typedef In Dart?
A function typedef, or function-type alias, gives a function type a name that you can use when declaring fields and return types. A typedef retains type information when a function type is assigned to a variable. Nowadays the new generalized feature of Dart not only supports typedefs for functions but also any other types.
That's how to create and use typedef s in Dart / Flutter. You need to assign a type or a function signature to a typedef. Then, the created typedef can be used as a variable, field, parameter, or return value of a method.
A typedef, or function-type alias, gives a function type a name that you can use when declaring fields and return types. A typedef retains type information when a function type is assigned to a variable. But how do I use it? Why declaring fields with a function-type? When do I use it? What problem does it solve?
You can view the feature specification for Generalized type alisases for the full design document.
I want to preface this by pointing out that Dart used to only support typedefs for functions. The new generalized feature supports typedefs for any type.
typedef JsonMap = Map<String, dynamic>;
JsonMap parseJsonMap(String input) => json.decode(input) as JsonMap;
This is especially useful when you have multiple generic types (type parameters) that cause long type names that are tedious to type, for example Map<ScaffoldFeatureController<SnackBar, SnackBarClosedReason>, SnackBar>
. This can now be simplified using a type alias:
typedef ScaffoldSnackBarMap = Map<ScaffoldFeatureController<SnackBar, SnackBarClosedReason>, SnackBar>;
If not clear from the above examples, this is the syntax for type alisases / typedefs:
'typedef' identifier typeParameters? '=' type ';'
This means that you always need to start with the typedef
keyword followed by your desired identifier, e.g. FooTypeDef
. After that, you can add type parameters, e.g. Foo<K, V>
. The last step is adding the =
symbol followed by the actual type you want to create an alias for. This can be any type, i.e. a class, primitive type, function type, or w/e. Do not forget the ;
at the end ;)
// Type parameters / generic types in typedef.
typedef Foo<K, V> = Map<K, V>;
// Type alias for regular types.
typedef Bar = Widget;
// As well as primitive types.
typedef Baz = int;
// Function types are also supported.
typedef FooFunction<T, R> = R Function(T param);
Additionally, you can use typedef
s for any class names. Say you want to rename your class from Provider
to Pod
because you think the former is too verbose. If you are maintaining a package, this would be a breaking change. With the new generalized type aliases, you can simply rename your class and create a type alias that you deprecate:
class NewClassName<T> {}
@Deprecated("Use NewClassName instead")
typedef OldClassName<T> = NewClassName<T>;
Note that this example and the one above are taken from the proposed CHANGELOG entry for the feature.
The feature will be shipped by default with Dart 2.13 but is currently still experimental. I will cover how to use it in both ways; the experimental method can be removed later on.
As I mentioned previously, the feature will be enabled by default starting with Dart 2.13. If you currently have Dart 2.13 installed already (you can use dart --version
to check it for example), you can use this method. Otherwise, you should refer to the Experimental support section below.
In your pubspec.yaml
, you need to define the lower bound on your Dart SDK constraint to be greater than or equal to 2.13.0
:
environment:
dart: '>=2.13.0 <3.0.0'
In your Flutter project (or any other Dart project), you currently need to enable them as an experiment. It means that they are hidden behind a feature flag.
Experimental Dart features can be configured using analysis_options.yaml
. You can simply create an analysis_options.yaml
file in the root of your project directory and add the following lines:
analyzer:
enable-experiment:
- nonfunction-type-aliases
Now, you need to also enable the experiment when you run (or build) your app:
flutter run --enable-experiment=nonfunction-type-aliases
To make sure that you can use this feature, use the master
channel (flutter channel master
when using Flutter).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With