typedefで関数型を定義出来ますが、Functionを使いましょうというお話です。
Stringを引数にとり、int型を返す関数は
typedef int LegacyTypeDef(String message);
int echo(String message){
print(message);
return 0;
}
void echoWithoutReturn(String message){
print(message);
}
LegacyTypeDef legacyTypeDef = echo;
legacyTypeDef('legacyTypeDef');
//LegacyTypeDef legacyTypeDef = echoWithoutReturn; //戻り値型が違うのでエラー
で定義&使用できますが、
typedef int LegacyTypeDef(String);
LegacyTypeDef legacyTypeDef = echo; //エラー
だとエラーになります。引数の所に型(String)しか書いていない場合は引数名と解釈され、dynamic型のStringという引数を取る関数と見なされてしまうからです。使わない引数名も定義に含めないといけないのは嫌ですよね。そこでFunctionを使います。
typedef NewTypeDef = int Function(String); //Functionを使えば引数名なしでOK
NewTypeDef newTypeDef = echo;
newTypeDef('newTypeDef');
Genericも使えます
//Generic使う
typedef NewTypeDefWithGeneric<T,M> = M Function(T);
NewTypeDefWithGeneric<String,int> newTypeDefWithGeneric = echo;
newTypeDefWithGeneric('newTypeDefWithGeneric');
ここまでをまとめるとこんな感じ。
//typedef int LegacyTypeDef2(String); //引数名省略するとdynamic型の引数名Stringと解釈されてしまう
typedef int LegacyTypeDef(String message);
typedef NewTypeDef = int Function(String); //Functionを使えば引数名なしでOK
//Generic使う
typedef NewTypeDefWithGeneric<T,M> = M Function(T);
void main() {
LegacyTypeDef legacyTypeDef = echo;
//LegacyTypeDef legacyTypeDef = echoWithoutReturn; //戻り値型が違うのでエラー
NewTypeDef newTypeDef = echo;
NewTypeDefWithGeneric<String,int> newTypeDefWithGeneric = echo;
legacyTypeDef('legacyTypeDef');
newTypeDef('newTypeDef');
newTypeDefWithGeneric('newTypeDefWithGeneric');
}
int echo(String message){
print(message);
return 0;
}
void echoWithoutReturn(String message){
print(message);
}
Dart公式もFunctionを使う方法を推奨しています。
Effective Dart:https://dart.dev/guides/language/effective-dart/design#dont-use-the-legacy-typedef-syntax
Lint:https://dart-lang.github.io/linter/lints/prefer_generic_function_type_aliases.html