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);

Your full example before

Your full example after

为什么需要这个 return 类型注释?这是因为 Flow 不推断多态类型。如果函数总是 returned a string,那也没关系。但是因为它returns Mappable<B>,所以需要注释。

这是另一个解决此问题的答案: