tcomb icon indicating copy to clipboard operation
tcomb copied to clipboard

t.func.getOptionalArgumentsIndex returns invalid values for type Any or Nil

Open lilobase opened this issue 8 years ago • 2 comments

Hello, First of all thanks for this amazing library, you help me get my sanity back when using javascript :) I have a strange behavior when I use optional parameters Nil or Any with the t.func combinator.

Version

"tcomb": "^3.2.16",

Expected behaviour

When I have a function with an optional parameters t.Any or t.Nil :

  const typedAction = t.func(t.maybe(t.Any), t.Any);
  const action = typedAction.of(x => x);

When I call it without arguments:

action();

I should get the result of the function: undefined

Actual behaviour

I get an error about the arity of the function:

TypeError: [tcomb] Invalid value [] supplied to arguments of function (Any) => Any (expected an array of length 1)

I have notice that the function t.func.getOptionalArgumentsIndex return 1 when an option<Any> or option<Ni>l is given:

console.log(t.func.getOptionalArgumentsIndex([t.maybe(t.String)])); //returns 0 as expected
console.log(t.func.getOptionalArgumentsIndex([t.maybe(t.Any)])); //returns 1
console.log(t.func.getOptionalArgumentsIndex([t.maybe(t.Nil)])); //returns 1

Do I misuse tcomb on this specific case ?

Thanks, Arnaud

lilobase avatar Feb 10 '17 14:02 lilobase

mhh I think you hit a corner case, an implicit assumption is that you shouldn't use t.maybe(t.Any) nor t.maybe(t.Nil) because

t.maybe(t.Any) = t.Any
// and
t.maybe(t.Nil) = t.Nil

EDIT: = as sets

gcanti avatar Feb 10 '17 15:02 gcanti

My specific corner case was to be able to specify an optional type which can be set by the user with a default value, my production code looks like this:

const actionCreator = (name, type = t.Nil, defaultValue = undefined) => {
  const actionCreatorType = t.func([t.maybe(type), t.maybe(t.Boolean)], t.Object, name);
  return actionCreatorType.of((payload = defaultValue, error = false) => ({
        payload: type(payload),
        error: error
    }));
};

//usage: 

const clearCache = actionCreator('clearCache'); //my function doesn't need any payload
clearCache(); //I get an error here !

const addLocation = actionCreator('addLocation', t.String, 'a default location'); 
addLocation(); //returns 'a default location' as expected
addLocation('another location') //returns 'another location' as expected

So, I will make a specific case for the case without payload.

lilobase avatar Feb 10 '17 15:02 lilobase