获取从元组联合中选择的流程

时间:2018-02-27 13:36:00

标签: javascript flowtype

我有一个返回元组联合的函数,看起来无论我做什么,flow都无法选择其中一个元组。示例(try flow link):

readonly
最后一行的

declare function genNumber(): [Error, null] | [null, number]; const [err, num] = genNumber(); if (err) { throw err; } // num should now be a number, but I can't convince flow of this (num: number); 显然应为num,但流程仍然认为它是number。我有几个解决方法,即将错误检查转到null | number,或者只是生成函数谎言并将返回类型更改为if (!num) {但我真的很讨厌这两个。

1 个答案:

答案 0 :(得分:0)

我认为您的问题是对结果进行解构,因为分析无法确定哪种返回类型适用。文档中提供了一个可能的解决方案,“Disjoint unions with exact types”,您在第二个示例(Try it here)中实现了类似的功能。

type Success = {| success: false, error: Error |}
type Failure = {| success: true, num: number |}

declare function genNumber(): Success | Failure;

const result = genNumber();

if (!result.success) {
  throw result.error;
}

// num should now be a number
(result.num: number);

更新: 目前似乎无法在流中处理节点样式回调(Github issue)。

以下是如何定义节点回调(Try):

type Completion = (err: ?Error, result: ?number) => void;

function myFunc(done: Completion) {
  done(null, 1);
}

myFunc((err, result) => {
  if (err) throw err;

  if (result) (result: number);

});

以下是您的元组定义方式(Try):

declare function genNumber(): [?Error, ?number];

const [err, num] = genNumber();

if (err) {
  throw err;
}

if (num) {
  (num: number);
}

虽然这仍然没有你想象的那么干净。我无法使用Flow Try将Promise的版本作为输入和返回类型传递,它似乎不喜欢await关键字(Try)。

async function gen<T>(promise: Promise<T> | T): Promise<[?Error, ?T]> {
    return new Promise((resolve, reject) => {
        Promise.all([promise])
            .then(result => resolve([null, result[0]]))
            .catch(e => reject([e, null]));
    });
}

const [ err, num ] = await gen(1);

if (err) throw err;

if (num) (num:number);