所以我在用流程键入的js中有以下管道函数:
const pipe = (...fns: $ReadOnlyArray<any>): any => (param: any) => fns.reduce((result, fn) => fn(result), param)
而且我希望也许允许some键入并像这样使用mixed
类型:
const pipe = (...fns: $ReadOnlyArray<mixed>): mixed => (param: mixed) => fns.reduce((result, fn) => fn(result), param)
但是流程给出错误消息:
流程:错误推断-fn(由于mixed [1]不是函数,因此无法调用“ fn”。)
如果我必须使用any
类型,这不是世界末日,但是我想知道为什么我不能使用mixed
类型?我的意思是允许根据文档采取功能:https://flow.org/en/docs/types/mixed/
按照定义,该函数接受任意数量的参数,可以是任何参数。是的,它包括功能,但也包括数字。如果您呼叫pipe(5)
,会发生什么?
相反,似乎您只想将其限制为功能。这很简单-只需将$ReadOnlyArray<mixed>
替换为ReadOnlyArray<mixed => mixed>
。进行此更改后,函数将进行类型检查。
但是,这仍然不是一个非常有用的类型。由于结果为mixed
,因此使用它会令人沮丧。这意味着Flow对它的类型一无所知,因此您将不得不在使用前对其进行优化。而且,运行时优化只能走得那么远。
如果该函数是多态的,该函数将更加有用:
const pipe = <T>(...fns: $ReadOnlyArray<T => T>): (T => T) => {
return (param) => {
return fns.reduce((result, fn) => fn(result), param);
};
}
function plus5(x) { return x + 5; }
function times3(x) { return x * 3; }
const plus5times3 = pipe(plus5, times3);
(plus5times3(6): number);
// expected error
(plus5times3(6): string);
([playground)
现在,您可以实际调用它并获得有用的结果。如所写,由于类型推断,您有时可能会混淆类型错误,但是通常可以通过添加其他类型注释来解决。特别是,我建议在compose
的结果中添加类型注释,例如
const plus5times3: number => number = pipe(plus5, times3);