Flow 中的通用函数
Flow从面向对象程序中借鉴的最佳概念之一是泛型的概念。在许多情况下,泛型对于细化类型检查至关重要。
泛型在哪些地方有用?
假设你有一个函数memoize
。使用 Flow 类型,它可能看起来像这样:
function memoize(func: (key: any) => any): (key: any) => any {
const registry = new Map();
return function(key: any): any {
let value = registry.get(key);
if (typeof value === 'undefined') {
value = func(key);
registry.set(key, value);
}
return value;
};
}
问题是它会吞噬以下细节func
:
// Type is (val: number) => boolean
function isPrime(val: number): boolean {
// Implementation...
}
// Type is (key: any) => any
const memoizedIsPrime = memoize(isPrime);
// This gives an error, since `Sentinel` is not a number.
isPrime('Sentinel');
// This does not give an error, since 'Sentinel' is any.
memoizedIsPrime('Sentinel');
使其通用
它非常简单,只需在参数前用 V 形符号声明类型并将其用作类型即可:
// We're using `K` and `V` here for convention, but you can name them pretty much anything.
export default function memoize<K, V>(func: (key: K) => V): (key: K) => V {
const registry = new Map();
return function(key: K): V {
let value = registry.get(key);
if (typeof value === 'undefined') {
value = func(key);
registry.set(key, value);
}
return value;
};
}
Flow 将推断其余内容:
// Type is (val: number) => boolean
function isPrime(val: number): boolean {
// Implementation...
}
// Type is (key: K) => V. Flow infers that `K` is number and `V` is boolean.
const memoizedIsPrime = memoize(isPrime);
// This gives an error, since `Sentinel` is not a number.
isPrime('Sentinel');
// This gives an error, since 'Sentinel' is a 'K' (number).
memoizedIsPrime('Sentinel');