有什么方法可以在 dart 中实现变量类型提升(注释一个函数以返回“is of type”值而不是普通的
bool
,类似于 TypeScript 的 类型谓词)或者我必须使用 null 检查运算符吗?
在 dart 中,我经常遇到这样的情况:我必须检查函数接收到的参数是否为 null 或者空 String/Iterable/Map。对于必须以相同方式处理 null 或空值的地方,我没有编写
if (value != null && value.isNotEmpty) ...
,而是使用 isTruthy
getter 函数在 String、Iterable 和 Map 类型上创建了扩展,该函数内部具有 null 相等性和 isNotEmpty 检查。例如,String?
类型的扩展如下所示:
extension MaybeStringExtension on String? {
/// Returns `false` if it is `null` or an empty string, `true` otherwise.
bool get isTruthy => this != null && this!.isNotEmpty;
}
问题是,在
isTruthy
检查其他函数之后,变量不会从类型 String?
提升到 String
并且 dart 分析器抱怨“参数类型‘String?’无法分配给参数类型“String”。”如果我不添加空检查运算符“!”,则会出错。例如:
bool isValidPassword(String? value) {
// This way value gets promoted to type `String` and don't have to add `!` operator.
return value != null && value.isNotEmpty && passwordRegExp.hasMatch(value);
// This way value doesn't get promoted to type `String` and have to add `!` operator.
return value.isTruthy && passwordRegExp.hasMatch(value!);
}
在 TypeScript 中,函数可以返回 类型谓词,在调用它们后提升变量类型,例如:
function isTruthy(value: string | null) : value is string {
return value != null && value.length != 0;
}
function someOtherFunc(value: string | null) {
if (isTruthy(value)) value.charAt(0); // value is of type string here
}
您可以通过模式匹配轻松完成此操作:
bool isValidPassword(String? input) => switch(input) {
String s? when passwordRegExp.hasMatch(s) => true,
_ => false,
};