我想定义一个像
这样的重载函数function first(n?: number) {
if (number === undefined) {
// returns a single Item
return items[0];
}
// returns an array of Item
return items.slice(0, n);
}
以便这些语句类型检查:
const item: Item = first(); // no args, so return type is Item
const items: Array<Item> = first(5); // number arg, so return type is Array<Item>
flow知道第一次调用first
会导致n === undefined
(因为如果undefined
对n
无效,它会抱怨)并且它理解然后它将采用if分支,所以我认为它可以推断返回类型是Item
,但我尝试过的任何东西都可以让任何通过或总是失败。
任何想法是否可能?在此先感谢互联网。
答案 0 :(得分:4)
我没有完整的解决方案,但我在那里得到了一段时间:
const items = [1, 2, 3];
type FirstType = ((_: void) => number) & ((n: number) => Array<number>);
const first: FirstType = (n?: number) => {
if (n === undefined) {
// returns a single Item
return (items[0]: any);
} else {
// returns an array of Item
return (items.slice(0, n): any);
}
}
const a: number = first();
const b: Array<number> = first(2);
(tryflow)
&
是一种交集类型,这意味着first
必须满足这两种类型的。您可以看到first()
的调用以您想要的方式进行类型检查。
不幸的是,似乎Flow目前无法对first
的主体进行类型检查。请注意,我必须通过any
强制转换返回值以逃避类型检查器。如果你愿意放弃函数体中的类型检查,你至少可以在调用函数的地方使用它。
答案 1 :(得分:0)
这可能不适用于您编写 OP 时当前的 Flow 版本,但是尝试使用最新版本时,我发现您甚至可以在源文件中使用 declare function
来避免 {{ 的可怕语法1}}。
((_: void) => number) & ((n: number) => Array<number>)
对于类方法,我发现的唯一方法是使用丑陋的 type Item = number;
const items: Array<Item> = [0, 1, 2, 3, 4];
declare function first(): Item;
declare function first(n: number): Array<Item>;
function first(n?: number): Item | Array<Item> {
if (n === undefined) {
// returns a single Item
return items[0];
}
// returns an array of Item
return items.slice(0, n);
}
const item: Item = first(); // no args, so return type is Item
const items2: Array<Item> = first(5); // number arg, so return type is Array<Item>
语法单独声明字段类型(是否在字段声明之前使用 &
无关紧要) :
declare