我正在尝试围绕lodash的isEqual
函数创建一个类型化的包装器。我希望它只适用于同一类型的两个参数。我有以下代码:
export function isEqual<T>(a: T, b: T): boolean {
return _.isEqual(a, b);
}
const c: boolean = isEqual('one', 2); // shouldn't it be a type error here?
console.log(c)
但它不起作用,因为可以将两个不同类型的参数传递给它,Flow就可以了。实现这样一个功能的正确方法是什么?
我正在使用Flow版本0.58.0
答案 0 :(得分:1)
经过一番研究后,我可以解释导致这种行为的原因。 T
隐式扩展为联合类型isEqual<string|number>(a: string|number, b: string:number)
。我不能告诉你为什么,但它在github上有描述。
从上面github评论中的示例中,我使用幻像类型P
提取了一个解决方案(或者说是一个hack):
type __R<T, T> = T;
type _R<T> = __R<*, T>;
type _Eq<T, U: _R<T>> = (T, U) => boolean;
type Eq<P> = _Eq<*, *>;
const eq:Eq<any> = (a, b) => a === b;
eq(true, false); // type checks
eq(1, 2); // type checks
eq(true, "foo"); // doesn't type check
可能有一个不那么混乱的解决方案,但仍然遗憾的是,流程不仅仅统一具有相同名称且具有相同类型的相同范围的类型变量。