flowtype:如何通过参数 count/types 重载函数 return 类型?
flowtype: how can i overload function return types by argument count/types?
我想定义一个重载函数,比如
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 分支,所以我认为它可以推断出 return 类型是 Item
,但我尝试过的一切要么让任何事情通过,要么总是失败。
知道这是否可能吗?提前感谢互联网。
我没有适合您的完整解决方案,但我已经做到了:
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
必须同时满足both。您可以看到对 first()
的调用按照您想要的方式进行了类型检查。
不幸的是,Flow 目前似乎无法对 first
的正文进行类型检查。请注意,我必须将 return 值转换为 any
以转义类型检查器。如果你愿意放弃在你的函数体中进行类型检查,你至少可以在调用函数的地方得到它。
这可能不适用于您编写 OP 时的最新 Flow 版本,但尝试使用最新版本,我发现您甚至可以在源文件中使用 declare function
以避免可怕的语法((_: 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>
对于 class 方法,我发现的唯一方法是使用丑陋的 &
语法单独声明字段类型(无论您之前是否使用 declare
字段声明与否):
class Foo {
foo: ((x: number) => string) & ((x: string) => number)
foo(x: number | string): number | string {
if (typeof x === 'number') return String(x)
else return Number(x)
}
}
const foo = new Foo()
const a: number = foo.foo('1')
const b: string = foo.foo(2)
我想定义一个重载函数,比如
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 分支,所以我认为它可以推断出 return 类型是 Item
,但我尝试过的一切要么让任何事情通过,要么总是失败。
知道这是否可能吗?提前感谢互联网。
我没有适合您的完整解决方案,但我已经做到了:
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
必须同时满足both。您可以看到对 first()
的调用按照您想要的方式进行了类型检查。
不幸的是,Flow 目前似乎无法对 first
的正文进行类型检查。请注意,我必须将 return 值转换为 any
以转义类型检查器。如果你愿意放弃在你的函数体中进行类型检查,你至少可以在调用函数的地方得到它。
这可能不适用于您编写 OP 时的最新 Flow 版本,但尝试使用最新版本,我发现您甚至可以在源文件中使用 declare function
以避免可怕的语法((_: 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>
对于 class 方法,我发现的唯一方法是使用丑陋的 &
语法单独声明字段类型(无论您之前是否使用 declare
字段声明与否):
class Foo {
foo: ((x: number) => string) & ((x: string) => number)
foo(x: number | string): number | string {
if (typeof x === 'number') return String(x)
else return Number(x)
}
}
const foo = new Foo()
const a: number = foo.foo('1')
const b: string = foo.foo(2)