typedef is a type alias mechanism in Dart that allows you to define short, readable names for complex types.
\\\\n\\\\nThis chapter introduces two uses of typedef: traditional function type aliases, and generic type aliases introduced in Dart 3.0.
\\\\n\\\\n\\\\n\\\\n
typedef Function Type Alias
\\\\n\\\\nWhen a function type is used frequently, typedef can give it a clear name.
\\\\n\\\\nThis is particularly useful for callback functions, event handlers, and similar scenarios.
\\\\n\\\\nExample
\\\\n\\\\n// Define a function type alias\\\\n// Represents: a function that takes two int parameters and returns an int\\\\n\\\\ntypedef IntOperation = int Function(int a, int b);\\\\n\\\\n// Define a callback type\\\\n// Represents: a function that takes a String message and returns void\\\\n\\\\ntypedef MessageCallback = void Function(String message);\\\\n\\\\n// Use typedef as parameter type\\\\n\\\\nint performOperation(int x, int y, IntOperation operation) {\\\\n return operation(x, y);\\\\n}\\\\n\\\\nvoid logMessage(String msg, MessageCallback callback) {\\\\n print('Preparing to output message...');\\\\n callback(' $msg');\\\\n}\\\\n\\\\nvoid main() {\\\\n // Pass a function that matches the IntOperation signature\\\\n int add(int a, int b) => a + b;\\\\n int multiply(int a, int b) => a * b;\\\\n\\\\n print('10 + 5 = ${performOperation(10, 5, add)}');\\\\n print('10 Γ 5 = ${performOperation(10, 5, multiply)}');\\\\n\\\\n // Can also pass an anonymous function directly\\\\n int result = performOperation(20, 4, (a, b) => a ~/ b);\\\\n print('20 Γ· 4 = $result');\\\\n\\\\n // Use MessageCallback\\\\n logMessage('Operation completed', (msg) {\\\\n print('Message received: $msg');\\\\n });\\\\n}\\\\n\\\\n\\\\n10 + 5 = 15\\\\n10 Γ 5 = 50\\\\n20 Γ· 4 = 5\\\\nPreparing to output message...\\\\nMessage received: Operation completed\\\\n\\\\n
Without typedef, you would need to repeatedly write verbose function type signatures at every parameter position.
\\\\n\\\\nWith typedef, type declarations become clear and unified, and modifications only need to be made in one place.
\\\\n\\\\n\\\\n\\\\n\\\\ntypedef is just an alias for a type; it does not create a new type. IntOperation and int Function(int, int) are completely equivalent in the type system.
\\\\n
\\\\n\\\\n
Function Types as Parameters
\\\\n\\\\nIn Dart, functions are first-class citizens and can be passed like ordinary values.
\\\\n\\\\nExample
\\\\n\\\\n// Directly use function type to declare parameters (without typedef)\\\\nvoid processNumbers(\\\\n List numbers,\\\\n bool Function(int) filter,\\\\n String Function(int) formatter,\\\\n) {\\\\n var filtered = numbers.where(filter);\\\\n for (var n in filtered) {\\\\n print(formatter(n));\\\\n }\\\\n}\\\\n\\\\n// Higher-order function that returns a function\\\\nint Function(int) makeMultiplier(int factor) {\\\\n // The returned closure captures factor\\\\n return (int n) => n * factor;\\\\n}\\\\n\\\\nvoid main() {\\\\n var scores = [55, 78, 92, 60, 45, 88];\\\\n\\\\n print('--- Passing score ---');\\\\n processNumbers(\\\\n scores,\\\\n (n) => n >= 60, // filter condition\\\\n (n) => 'TUTORIAL Minutenumber: $n Minute', // formatter\\\\n );\\\\n\\\\n print('--- High MinuteοΌ> 80οΌ---');\\\\n processNumbers(\\\\n scores,\\\\n (n) => n > 80,\\\\n (n) => 'High Minute: $n Minute',\\\\n );\\\\n\\\\n // Function as return value\\\\n var doubler = makeMultiplier(2);\\\\n var tripler = makeMultiplier(3);\\\\n\\\\n print('5 Γ 2 = ${doubler(5)}');\\\\n print('5 Γ 3 = ${tripler(5)}');\\\\n}\\\\n \\\\n\\\\n--- Passing score ---\\\\nTUTORIAL Minutenumber: 78 Minute\\\\nTUTORIAL Minutenumber: 92 Minute\\\\nTUTORIAL Minutenumber: 60 Minute\\\\nTUTORIAL Minutenumber: 88 Minute\\\\n--- High MinuteοΌ> 80οΌ---\\\\nHigh Minute: 92 Minute\\\\nHigh Minute: 88 Minute\\\\n5 Γ 2 = 10\\\\n5 Γ 3 = 15\\\\n\\\\n
\\\\n\\\\n
Callback Pattern
\\\\n\\\\nThe callback pattern is the most common application scenario for function types.
\\\\n\\\\nIt gives control of "what to do" to the caller, making code more flexible and reusable.
\\\\n\\\\nExample
\\\\n\\\\n// Define callback types\\\\ntypedef ResultCallback = void Function(T result);\\\\ntypedef ErrorCallback = void Function(String error);\\\\n\\\\n// Simulate asynchronous operation\\\\nvoid fetchUserData(\\\\n String userId, {\\\\n required ResultCallback \\\\n\\\\nFetching User data...\\\\nFetch Success!\\\\nUsername: TUTORIAL User\\\\nLevel: VIP\\\\n---\\\\nFetching User data...\\\\nFetch Failure: User unknown Does not exist\\\\n\\\\n
Common application scenarios for the callback pattern:
\\\\n\\\\n| Scenario | \\\\nCallback Type Example | \\\\n
|---|---|
| Network request | \\\\nonSuccess(data) / onError(error) | \\\\n
| UI event | \\\\nonTap() / onLongPress() | \\\\n
| Data transformation | \\\\nCallbacks in map(), where(), reduce() | \\\\n
| Timer | \\\\nTimer(callback, duration) | \\\\n
| Animation complete | \\\\nonComplete() | \\\\n
\\\\n\\\\n\\\\nAlthough the callback pattern is flexible, it can lead to "callback hell" when dealing with multiple layers of asynchronous operations. Dart provides async/await to handle asynchronous flows more elegantly, which we will cover in detail in Chapter 17.
\\\\n
\\\\n\\\\n
Dart 3.0 Generic Type Aliases
\\\\n\\\\nDart 3.0 extends the capabilities of typedef, so you can now create aliases for any type, not just function types.
\\\\n\\\\nExample
\\\\n\\\\n// Dart 3.0: typedef can create aliases for any type\\\\n\\\\n// Aliases for complex collection types\\\\ntypedef JsonMap = Map;\\\\ntypedef UserList = List \\\\n\\\\nProcessing JSON: {name: tutorial, age: 10, isVip: true}\\\\nNumber of keys: 3\\\\nSuccess: Operation Success\\\\nFailure: Network connection timed out\\\\nValidation passed: TUTORIAL\\\\nValidation Failure: Name must be at least 3 characters\\\\n\\\\nDart 3.0 type aliases greatly reduce verbose type declarations, making code more concise and readable.
\\\\n\\\\n\\\\nType aliases (typedef) and the types themselves are completely equivalent at runtime; they are just "nicknames" at compile time. This means you cannot use typedef to distinguish between two types with the same structure but different semanticsβthey will be treated as the same type.
\\\\n
YouTip