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

问题描述 投票:1回答:1

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

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) {,或者只是生成函数谎言并将返回类型更改为[Error, ((null: any): number)] | [null, number]但我真的很讨厌这两个。

javascript flowtype
1个回答
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尝试传递一个版本的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);
© www.soinside.com 2019 - 2024. All rights reserved.