死代码(Ramda类型decelration)打破流

时间:2016-10-01 09:48:59

标签: flowtype ramda.js

我从Ramda借用了tail函数的声明:

declare function tail<T,V:Array<T> | string>(xs: V): V;

我的类型Query基本上是ReaderT Promise monad:

// @flow

class Query<C, T> {
  run: (config: C) => Promise<T>;
  constructor(runner : (config: C) => Promise<T>) {
    this.run = runner
  }
  bind <U>(f : ((a: T) => Query<C, U>) ) : Query<C, U> {
    return new Query(config => this.run(config).then(x => f(x).run(config)))
  }
  map <U>(f : (a: T) => U) : Query<C, U> {
    return new Query(config => this.run(config).then(f))
  }
}

使用此定义Flow无法键入以检查此表达式:

new Query(config => Promise.resolve(config + 1)) // config is {init: number}
.run({init: 2}).then(console.log)

Flow console

但是当我使用声明的sequence函数定义tail函数时(即使我从不调用sequence),Flow类型检查上面的错误表达式而没有任何错误:

const sequence = <C> (queries : Array<Query<C, any>>) : Query<C, Array<any>> => {
  if (queries.length == 0) {
    return new Query(t => Promise.resolve([]))
  } else {
    return queries[0].bind(x => sequence(tail(queries)).map(ys => [x].concat(ys)))
  }
}

Flow console

我应该注意,如果我将tail的类型更改为:

,Flow会正确识别类型错误
declare function tail<T,V:Array<T>>(xs: V): V;

(通过删除总和类型)

Flow console

我出错了还是Flow中的错误?

1 个答案:

答案 0 :(得分:2)

似乎肯定是一个错误。我设法缩短了失败的测试

// @flow

declare function tail<T,V:Array<T> | string>(xs: V): V;

class Query<C, T> {
  run: (config: C) => Promise<T>;
  constructor(runner : (config: C) => Promise<T>) {
    this.run = runner
  }
  chain <U>(f : (a: T) => Query<C, U> ) : void {
  }
}

function wat<C, T>(queries : Array<Query<C, T>>) : void {
  tail(queries)
}

// $ExpectError
new Query(config => Promise.resolve(config + 1)).run({init: 2})