Flowtype Javascript 推理未按预期工作
Flowtype Javascript Inference Not Working as Expected
如果参考 #2 未被注释掉,我无法弄清楚为什么 Flow 无法从参考 #1 映射函数正确推断出 return 类型。
如果参考 #2 被注释掉,或者如果我明确地将 Mappable<B>
表示为参考 #1 的 return 类型,一切都很好。
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>): Mappable<B> => mappable.map(transform);
很想知道为什么会这样!谢谢!
// Types
type Transform<A, B> = (value: A) => B;
// Classes
class Mappable<A> {
__value: A;
constructor(value: A) {
this.__value = value;
}
map<B>(transform: Transform<A, B>): Mappable<B> {
return new Mappable(transform(this.__value));
}
}
class Container<A> extends Mappable<A> {}
// Transformations
const stringToBase10Number = (value: string): number => parseInt(value, 10);
const numberToString = (value: number): string => value.toString();
// Map Utility (Reference #1)
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>) => mappable.map(transform);
// Log Utility
const log = <T>(value: T): T => { console.log(value); return value; }
// Test Case
const fooContainer = new Container('10');
const fooNumberContainer = map(stringToBase10Number, fooContainer);
map(log, fooNumberContainer); // Logs '1' to the console
// Reference #2
const fooStringContainer = map(numberToString, fooNumberContainer);
map(log, fooStringContainer);
错误:
const fooStringContainer = map(numberToString, fooNumberContainer);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>) => mappable.map(transform);
^ B. This type is incompatible with
const numberToString = (value: number): string => value.toString();
^^^^^^ number
尝试将 return 类型添加到 map
函数。所以改变
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>) => mappable.map(transform);
到
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>): Mappable<B> => mappable.map(transform);
为什么需要这个 return 类型注释?这是因为 Flow 不推断多态类型。如果函数总是 returned a string
,那也没关系。但是因为它returns Mappable<B>
,所以需要注释。
这是另一个解决此问题的答案:
如果参考 #2 未被注释掉,我无法弄清楚为什么 Flow 无法从参考 #1 映射函数正确推断出 return 类型。
如果参考 #2 被注释掉,或者如果我明确地将 Mappable<B>
表示为参考 #1 的 return 类型,一切都很好。
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>): Mappable<B> => mappable.map(transform);
很想知道为什么会这样!谢谢!
// Types
type Transform<A, B> = (value: A) => B;
// Classes
class Mappable<A> {
__value: A;
constructor(value: A) {
this.__value = value;
}
map<B>(transform: Transform<A, B>): Mappable<B> {
return new Mappable(transform(this.__value));
}
}
class Container<A> extends Mappable<A> {}
// Transformations
const stringToBase10Number = (value: string): number => parseInt(value, 10);
const numberToString = (value: number): string => value.toString();
// Map Utility (Reference #1)
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>) => mappable.map(transform);
// Log Utility
const log = <T>(value: T): T => { console.log(value); return value; }
// Test Case
const fooContainer = new Container('10');
const fooNumberContainer = map(stringToBase10Number, fooContainer);
map(log, fooNumberContainer); // Logs '1' to the console
// Reference #2
const fooStringContainer = map(numberToString, fooNumberContainer);
map(log, fooStringContainer);
错误:
const fooStringContainer = map(numberToString, fooNumberContainer);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>) => mappable.map(transform);
^ B. This type is incompatible with
const numberToString = (value: number): string => value.toString();
^^^^^^ number
尝试将 return 类型添加到 map
函数。所以改变
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>) => mappable.map(transform);
到
const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>): Mappable<B> => mappable.map(transform);
为什么需要这个 return 类型注释?这是因为 Flow 不推断多态类型。如果函数总是 returned a string
,那也没关系。但是因为它returns Mappable<B>
,所以需要注释。
这是另一个解决此问题的答案: