我有一个返回元组联合的函数,看起来无论我做什么,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) {
但我真的很讨厌这两个。
答案 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);