让我们考虑ts-opt包中的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)
答案 0 :(得分:1)
实现这一目标的一种方法(不使用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
。