typescript - 如何通过传递的保护函数缩小泛型类型?
问题描述
Opt
让我们考虑ts-opt包(它只是一个 Maybe/Option/Optional)并isNumber
有一个类型保护 ( (x): x is number => ...
)。
是否可以以通用方式实现(以及如何)方法someIf
(使用任意类型保护,类型安全,无需用户指定已经在类型保护中的类型):
type A = number | string;
const x: A = 4;
const y: A = 'y';
opt(x) // Opt<number | string>
.someIf(isNumber); // Opt<number> (Some(4))
opt(y) // Opt<number | string>
.someIf(isNumber); // Opt<number> (None)
解决方案
实现这一点的一种方法(没有someIf
作为原型函数)如下
type A = number | string;
const x: A = 4;
const y: A = "y";
const isNumber = (a: any): a is number => typeof a === "number";
const someIf = <T>(ot: Opt<any>, f: (x: any) => x is T): Opt<T> =>
ot.caseOf(
t => (f(t) ? opt(t) : none),
() => none
);
const ox = someIf(
opt(x),
isNumber
); // Opt<number> <- Some(4)
const oy = someIf(
opt(y),
isNumber
); // Opt<number> <- None
这个想法很简单。折叠可选值,如果none
,我们无事可做。否则,根据类型保护验证包装的值。如果守卫成功,只需返回值(现在缩小其类型),否则返回none
。
推荐阅读
- r - 在大型分箱数据集上使用“ggplot”时的内存泄漏
- wordpress - 利用浏览器缓存使用 .htaccess
- java - 正则表达式查找带方括号的字符串并替换
- ubuntu-14.04 - iopl() 间歇性失败
- java - Android - 如何在新 API 中请求位置更新?
- laravel - 具有 Laravel 权限的 Vue.js
- reactjs - 想要使用在 ReactJS 中具有某些特定功能的 Calendar
- c# - 如何从 XmlNodeList 中删除特定项目
- python - 将 3 个不同 For 循环的结果显示到表格中
- ios - 在 Xcode 中存档反应本机应用程序时出错 - 多个命令产生“libyoga.a”