andreypopp / validated

Validate your configurations with precise error messages
91 stars 14 forks source link

Issues with Flow 0.66 #20

Closed pronebird closed 6 years ago

pronebird commented 6 years ago

Hi,

I am having lots of issues after upgrading to Flow 0.66.

I have the following helper for oneOf():

// Either expect:
// a. string - fixed 'any'
// = or =
// b. { only: T }
const Constraint = (constraintValue) => oneOf(string, object({
  only: constraintValue,
}));

// Should expand this to:
// a. string
// b. { only: { city: string } }
// c. { only: { country: a | b } }
const test = Constraint(oneOf(
  object({ city: string }),
  object({ country: Constraint(enumeration('a', 'b')) })
));

Emits the following error when used with Flow 0.66:

Cannot call Constraint with oneOf(...) bound to constraintValue because in type argument V [1]:
 - Either mixed [2] is incompatible with object type [3].
 - Or mixed [2] is incompatible with object type [3].

     app/lib/ipc-facade.js
      79|   only: constraintValue,
      80| }));
      81|
      82| const test = Constraint(oneOf(
      83|   object({ city: string }),
      84|   object({ country: Constraint(enumeration('udp', 'tcp')) })
      85| ));
      86|
      87| const RelaySettingsSchema = {};
      88|

     node_modules/validated/lib/schema.js.flow
 [1] 128| export class Node<V> {
        :
 [3] 305| ): Node<$ObjMap<S, <V>(v: Node<V>) => V>> { // eslint-disable-line no-undef
        :
 [2] 362| export class EnumerationNode<V> extends Node<mixed> {

It seems that once I nest oneOf something terrible happens.

pronebird commented 6 years ago

I realized that Flow picks up the definition for function on the first evaluation so the right thing to do is to add a generic parameter, i.e:

const Constraint = <T>(constraintValue: Node<T>) => oneOf(string, object({
  only: constraintValue,
}));