获取带有流的函数组合的输出类型

时间:2018-06-21 14:48:59

标签: flowtype

我希望flow确定应用函数组合的输出类型。例如,我想流程来推断o的类型为{ b: boolean }

const foo = s => s.length;
const bar = n => n > 3;
const baz = b => ({ b });

// The list of functions
const funcs = [foo, bar, baz];

// This is equivalent to: baz(bar(foo('hello')))
const o = funcs.reduce((acc, func) => func(acc), 'hello');

console.log(o);  // { b: true }

我尝试过flow 0.74

// @flow

type Foo = string => number;
type Bar = number => boolean;
type Baz = boolean => {b: boolean};

const foo: Foo = (s: string): number => s.length;
const bar: Bar = (n: number): boolean => n > 3;
const baz: Baz = (b: boolean): {b: boolean} => ({ b });

// Ok, type is { b: boolean }, but I want to work with 
// the array of functions `funcs`:
const a = baz(bar(foo('hello')));
console.log(a);  // { b: true }

// We need Funcs type to be Tuple[Foo, Bar, Baz], not Array<Foo|Bar|Baz>
type Funcs = [Foo, Bar, Baz];
const funcs: Funcs = [foo, bar, baz];

// Ok, type is { b: boolean }, but array length is hardcoded:
const b = funcs[2](funcs[1](funcs[0]('hello')));
console.log(b);  // { b: true }

// Got flow error:
// Cannot call func with acc bound to the first parameter because:
//  • number [1] is incompatible with string [2].
//  • number [1] is incompatible with boolean [3].
//  • boolean [4] is incompatible with string [2].
//  • boolean [4] is incompatible with number [5].
//  • object type [6] is incompatible with string [2].
//  • object type [6] is incompatible with number [5].
//  • object type [6] is incompatible with boolean [3].
//  • string [7] is incompatible with number [5].
//  • string [7] is incompatible with boolean [3].
//
//  [2][1]  3│ type Foo = string => number;
//  [5][4]  4│ type Bar = number => boolean;
//  [3][6]  5│ type Baz = boolean => {b: boolean};
//           :
//         21│ const b = funcs[2](funcs[1](funcs[0]('hello')));
//         22│ console.log(b);  // { b: true }
//         23│
//     [7] 24│ const c = funcs.reduce((acc, func) => func(acc), 'hello');
//         25│ console.log(c);
//         26│
//         27│ //let x = 'hello';
const c = funcs.reduce((acc, func) => func(acc), 'hello');
console.log(c);

// Same error as above.
let d = 'hello';
for (let func of funcs) {
    d = func(d);
}
console.log(d);

如何在不对数组长度进行硬编码的情况下flow推断输出类型?

0 个答案:

没有答案