tcomb
tcomb copied to clipboard
t.func.getOptionalArgumentsIndex returns invalid values for type Any or Nil
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
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
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.