Understanding Typedefs (Type Aliases) in Dart and Flutter

Updated: March 31, 2023 By: Pennywise One comment

Flutter and Dart have gotten better and more popular recently. Many new features and improvements have been added.

In this article, we’ll explore typedefs in Dart (also known as type aliases) and go through a few examples of using them in practice. Function typedefs have been available since the first days of Dart, but non-function typedefs are new, and you need Dart 2.13 or later to use them.

Function Typedefs

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.

Example

The code:

import 'package:flutter/foundation.dart';

// Defining alias name
typedef SaySomething = void Function(String name);

void sayHello(String name) {
  if (kDebugMode) {
    print('Hello $name');
  }
}

void sayGoodbye(String name) {
  if (kDebugMode) {
    print('Goodbye $name');
  }
}

void main() {
  // Using alias
  SaySomething myFunction;

  myFunction = sayHello;
  myFunction('Kindacode.com');

  myFunction = sayGoodbye;
  myFunction('Pennywise The Clown');
}

Output:

Hello Kindacode.com
Goodbye Pennywise The Clown

Non-Function Typedefs

Nowadays the new generalized feature of Dart not only supports typedefs for functions but also any other types.

if you are using Dart version lower than 2.13, you’ll run into the following error:

 Error: Can't create typedef from non-function type. 

Note: To check or upgrade your Dart version, see this article.

Non-function typedefs are useful when you have multiple generic types (type parameters) that cause long type names. These long names might be hard to remember as well as increase the chance of making typos. Another benefit from typedefs is that in cases you want to change the type, you can change it in a single place instead of going through a bunch of code files in your project one by one.

Example

The code:

import 'package:flutter/foundation.dart';

typedef ID = int;
typedef Person = Map<String, dynamic>;

void main() {
  // Using ID typedef
  const ID x1 = 10;
  const ID x2 = 20;
  if (kDebugMode) {
    print(x1);
  }
  if (kDebugMode) {
    print(x2);
  }

  // Using Person typedef
  final Person personOne = {"name": "The Invisible Man", "age": 100};

  final Person personTwo = {"name": "Spinning Man", "age": 50};

  if (kDebugMode) {
    print(personOne);
  }
  if (kDebugMode) {
    print(personTwo);
  }
}

The output:

10
20
{name: The Invisible Man, age: 100}
{name: Spinning Man, age: 50}

Another Example

This example will use typedefs with widgets in Flutter.

The code:

// main.dart
import 'package:flutter/material.dart';

typedef ButtonList = List<ElevatedButton>;

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      // Remove the debug banner
      debugShowCheckedModeBanner: false,
      title: 'Kindacode.com',
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  HomePage({Key? key}) : super(key: key);

  final ButtonList _buttonList = [
    ElevatedButton(onPressed: () {}, child: const Text('Button 1')),
    ElevatedButton(onPressed: () {}, child: const Text('Button 2')),
    ElevatedButton(onPressed: () {}, child: const Text('Button 3')),
    ElevatedButton(onPressed: () {}, child: const Text('Button 4')),
    ElevatedButton(onPressed: () {}, child: const Text('Button 5')),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kindacode.com'),
      ),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: _buttonList,
      ),
    );
  }
}

The output:

Conclusion

Using typedefs makes your code more expressive and consistent. However, in some situations, overusing and abusing typedefs can possibly make your code become hard to read and understand. That’s why there’re developers who don’t like typedefs, and if you’re among them, it’s totally fine.

It’s great to see that Dart and Flutter are getting stronger and growing better with new features. Thanks to the talented people who’ve contributed to that greatness. Continue learning and keep the ball rolling by taking a look at the following articles:

You can also check out our Flutter topic page or Dart topic page for the latest tutorials and examples.

1 Comment
Inline Feedbacks
View all comments
Mahan Marwat
Mahan Marwat
2 years ago

Having a background in Python, this is the first time I am seeing typedefs. In one of your examples, I think using List<ElevatedButton> directly instead of ButtonList, is more readable and helpful than defining a typedef ButtonList.

Related Articles