简体   繁体   English

Flowtype Javascript推理未按预期工作

[英]Flowtype Javascript Inference Not Working as Expected

I'm unable to figure out why Flow cannot correctly infer the return type from the Reference #1 map function if Reference #2 is not commented out. 我无法弄清楚为什么如果未注释掉Reference#2,则Flow无法从Reference#1映射函数正确推断返回类型。

If Reference #2 is commented out OR if I explicitly denote Mappable<B> as the return type for Reference #1 all is good. 如果引用2被注释掉,或者如果我明确表示Mappable<B>作为引用1的返回类型,那么一切都很好。

const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>): Mappable<B> => mappable.map(transform);

Would love to know why this is working the way it is! 很想知道这为何如此运作! Thanks! 谢谢!

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

Error: 错误:

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

Try adding a return type to the map function. 尝试将返回类型添加到map函数。 So change 所以改变

const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>) => mappable.map(transform);

to

const map = <A, B>(transform: Transform<A, B>, mappable: Mappable<A>): Mappable<B> => mappable.map(transform);

Your full example before 您之前的完整示例

Your full example after 您之后的完整示例

Why is this return type annotation needed? 为什么需要此返回类型注释? It's because Flow does not infer polymorphic types. 这是因为Flow不能推断多态类型。 If the function always returned a string , it wouldn't matter. 如果函数总是返回一个string ,那就没关系了。 But since it returns Mappable<B> , the annotation is needed. 但是由于它返回Mappable<B> ,所以需要注释。

Here is another answer that also addresses this problem: Polymorphic Anonymous Functions Type Aliases 这是另一个解决此问题的答案: 多态匿名函数类型别名

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM